48

As part of my document in MongoDB I'm storing an array of objects. How can I query it for only the 4th element of the array for example? So I don't want the get the entire array out, just the 4th element.

1

3 Answers 3

76

Use $slice.

db.foo.find({ bar : "xyz" } , { my_array : { $slice : [n , 1] } } )

will retrieve the nth element of the array "my_array" of all documents in the foo collection where bar = "xyz".

Some other examples from the MongoDB documentation:

db.posts.find({}, {comments:{$slice: 5}}) // first 5 comments
db.posts.find({}, {comments:{$slice: -5}}) // last 5 comments
db.posts.find({}, {comments:{$slice: [20, 10]}}) // skip 20, limit 10
db.posts.find({}, {comments:{$slice: [-20, 10]}}) // 20 from end, limit 10

Which you can read here: http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields

Sign up to request clarification or add additional context in comments.

1 Comment

small correction to your line " db.foo.find({ bar : "xyz" } , { my_array : { $slice : [n , 1] } } ) will retrieve the nth element of the array "my_array" of all documents in the foo collection where bar = "xyz". " i think this will give the (n+1)th element from the array my_array because $slice : [n, 1] , means skip n , limit 1 , so it will return the n+1 th element from the array
24

You can use the $arrayElemAt operator new in MongoDB 3.2 to return the element at the specified array index.


Demo:

A collection named baskets contains documents that look like this:

{
    "_id" : ObjectId("578f326f6db61a299a383c5a"),
    "fruits" : [
        "apple",
        "mango",
        "banana",
        "apricot",
        "cherry"
    ]
}

The following query return the element at index -2 (second element) in the "fruits" array.

db.baskets.aggregate(
    [
        { "$project": { "matched": { "$arrayElemAt": [ "$fruits", 1 ] } } } 
    ] 
)

which produces

{ 
    "_id" : ObjectId("578f326f6db61a299a383c5a"), 
    "matched" : "mango" 
}

And the following query the element before the last element in the array; thus the element at index -2

db.baskets.aggregate(
    [
        { "$project": { "matched": { "$arrayElemAt": [ "$fruits", -2 ] } } } 
    ] 
)

which yields:

{ 
    "_id" : ObjectId("578f326f6db61a299a383c5a"), 
    "matched" : "apricot" 
}

1 Comment

For me, this is the Accepted Answer! I needed a way to swap between 2 elements in an array but couldn't find how to access an element by index upon an update. This $arrayElemAt operator saved me a ton.
9

Another way to do this is to use the update array syntax. Here, contribs.1 sets the second element in the contribs array to have value ALGOL 58 (Taken from the manual page on update syntax)

db.bios.update(
   { _id: 1 },
   { $set: { 'contribs.1': 'ALGOL 58' } }
)

2 Comments

But we are looking for get the element, not push the element :?
As the post makes no attempt to answer the original question and is not useful, consider downvoting it in order to give it a chance to be removed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.