Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB nested array query

I've asked this as a comment on another question, and also posted a question on mongodb-user. No responses so far, so I'm resorting to asking a separate question.

The documentation states:

If the field holds an array, then the $in operator selects the documents whose field holds an array that contains at least one element that matches a value in the specified array (e.g. , , etc.)

I'm using:

mongod --version: db version v2.2.2, pdfile version 4.5 Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267  mongo --version: MongoDB shell version: 2.0.4 

In MongoDB shell:

db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}}) 

Here's a list of queries that should work according to the documentation, and the results they produce:

Why doesn't this work?

> db.nested.findOne({'level1.level2.0': 'item00'}) null 

Why do I need the $all?

> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}}) {     "_id" : ObjectId("51a7a4c0909dfd8872f52ed7"),     "level1" : {         "level2" : [             [                 "item00",                 "item01"             ],             [                 "item10",                 "item11"             ]         ]     } } 

At least one of the following should work, right?

> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}}) null  > db.nested.findOne({'level1.level2': {'$in': ['item00']}}) null 

Any ideas? We're considering abandoning MongoDB if the query syntax doesn't work as advertised.

Thanks!

like image 871
dgorur Avatar asked Jun 25 '13 17:06

dgorur


People also ask

How to Query inside array in MongoDB?

To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object. Here is the query to search in an array of objects in MongoDB.

How do I access nested objects in MongoDB?

Accessing embedded/nested documents – In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks.

How to Query array of Embedded Documents?

Use the Array Index to Query for a Field in the Embedded Document. Using dot notation, you can specify query conditions for field in a document at a particular index or position of the array. The array uses zero-based indexing. When querying using dot notation, the field and index must be inside quotation marks.

How do I update a nested array in MongoDB?

Update Nested Arrays in Conjunction with $[]The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades. questions array if the associated grades.


2 Answers

After running some queries, I came to the conclusion that $in doesn't work for an array of arrays.

You can use $elemMatch instead and it'll work, but it is frustrating that MongoDB's documentation doesn't warn about it.

I created this document:

{       "_id": "51cb12857124a215940cf2d4",       "level1": [         [           "item00",           "item01"         ],         [           "item10",           "item11"         ]       ],       "items": [         "item20",         "item21"       ] } 

Notice that the field "items" is an array of strings and this query works perfectly:

db.nested.findOne({"items":{"$in":["item20"]} }) 

Now, "level1.0" is also an array of strings, the only difference is that it's inside another array. This query should work but isn't:

db.nested.findOne({"level1.0":{"$in":["item00"]} }) 

The only way to get the result is using $elemMatch:

db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} }) 

So $elemMatch solves the problem, but the real solution is to update MongoDB's documentation to states that $in doesn't work for arrays of arrays. Perhaps you should submit a request to 10gen.

like image 169
AntonioOtero Avatar answered Oct 03 '22 04:10

AntonioOtero


Use nested elemMatch to search nested levels within arrays.

Details Querying an array of arrays in MongoDB

like image 41
dgorur Avatar answered Oct 03 '22 03:10

dgorur