Lord Loh.
Lord Loh.

Reputation: 2477

How do I find documents with an element at a particular position in an array using MongoDB?

I would like to find all documents where element 0 of ingredients is apple. So I want to get document 1 and 3, but not 2. Is such a thing possible natively in Mongo?

The example as it is does not make sense, but my application was too complicated to put up here.

{
    _id => 1
    name => 'best smoothie' 
    ingredients => Array
        (
            [0] => apple
            [1] => raspberry
            [2] => orange
            [3] => banana
        )
}

 

{
    _id => 2
    name => 'summer smoothie' 
    ingredients => Array
        (
            [0] => lemon
            [1] => mint
            [2] => apple

        )
}

 

{
    _id => 3
    name => 'yogurt smoothie' 
    ingredients => Array
        (
            [0] => apple
            [1] => blueberry

        )
}

Example borrowed from - Querying array elements with Mongo.

Upvotes: 0

Views: 174

Answers (3)

WiredPrairie
WiredPrairie

Reputation: 59763

You can use the array positional operator (docs). What's useful is that you can use that same pattern and specify a specific index rather than using the general $ syntax.

Assuming this is your data:

> db.so1.insert({name:"best smoothie", ingredients: ['apple','raspberry','orange','banana']})
> db.so1.insert({name:"summer smoothie", ingredients: ['lemon','mint','apple']})
> db.so1.insert({name:"yogurt smoothie", ingredients: ['apple','blueberry']})

If you want limit the search to only index position 0, just add that to the array property name as shown below:

> db.so1.find({'ingredients.0':'apple'})

Results:

{
        "_id" : ObjectId("51c4425ff227e278e59f5df5"),
        "name" : "best smoothie",
        "ingredients" : [
                "apple",
                "raspberry",
                "orange",
                "banana"
        ]
}
{
        "_id" : ObjectId("51c4428af227e278e59f5df7"),
        "name" : "yogurt smoothie",
        "ingredients" : [
                "apple",
                "blueberry"
        ]
}

Upvotes: 4

Dmitry Zagorulkin
Dmitry Zagorulkin

Reputation: 8548

You should use $unwind with $project mongo functions.

`$unwind` - split up array
`$project` - add smth like index for each splitted element

after you could use simple findOne statement.

Upvotes: 1

Pierre-Louis Gottfrois
Pierre-Louis Gottfrois

Reputation: 17631

I don't see any way to achieve this using simple array. However here is what you could do using an array of hashes:

> db.collections.find()
{ "_id" : ObjectId("51c400d2b9f10d2c26817c5f"), "ingredients" : [ { "value1" : "apple" }, { "value2" : "orange" } ] }
{ "_id" : ObjectId("51c400dbb9f10d2c26817c60"), "ingredients" : [ { "value1" : "mint" }, { "value2" : "apple" } ] }
{ "_id" : ObjectId("51c400e1b9f10d2c26817c61"), "ingredients" : [ { "value1" : "apple" }, { "value2" : "lemon" } ] }

> db.collections.find({ ingredients: { $elemMatch: { value1: 'apple' }}})
{ "_id" : ObjectId("51c400d2b9f10d2c26817c5f"), "ingredients" : [ { "value1" : "apple" }, { "value2" : "orange" } ] }
{ "_id" : ObjectId("51c400e1b9f10d2c26817c61"), "ingredients" : [ { "value1" : "apple" }, { "value2" : "lemon" } ] }

Upvotes: 0

Related Questions