Nelson La Rocca
Nelson La Rocca

Reputation: 183

MongoDB finding within embedded documents

Using the example found at:

https://docs.mongodb.com/manual/tutorial/query-array-of-documents/

Having:

db.inventory.insertMany( [
   { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
   { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
   { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
   { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

and later querying:

db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

returns a set of documents having warehouse = A and qty=5 in "instock" subdocument

But querying just for those containing {warehouse: "A"} doesn't return any result

db.inventory.find( { "instock": { warehouse: "A" } } )

Now, changing that to:

db.inventory.find( { "instock.warehouse": "A" })

works out

Shouldn't be both the same ? Anything about the semantics ?

On the other hand, what's the correct way to find for a field value that's in list of subdocuments inside another list of subdocuments (embedded of embedded)

Thanks !

Upvotes: 0

Views: 191

Answers (1)

Rahul Raj
Rahul Raj

Reputation: 3459

When you hit the query: db.inventory.find( { "instock": { warehouse: "A" } } ) It checks for documents where instock array having only one field underneath it. In this case it just acts like $eq check. That's why you're getting zero results.

On the other hand, you have documents where both warehouse: "A" & qty: 5 are present.

That's why your second query: db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } ) return results.

The third query: db.inventory.find( { "instock.warehouse": "A" }) is the proper way to access fields inside embedded documents.

Instead of this query: db.inventory.find( { "instock": { warehouse: "A" } } )

You can also use $elemMatch for accessing fields inside array of documents. db.inventory.find({ "instock": {$elemMatch:{warehouse: "A"} }})

Upvotes: 1

Related Questions