0

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 !

Clifford
  • 88,407
  • 13
  • 85
  • 165
Nelson La Rocca
  • 173
  • 1
  • 9

1 Answers1

1

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"} }})

Rahul Raj
  • 3,197
  • 5
  • 35
  • 55
  • Thanks Rahul for your clear answer. using $elemMatch means loosing performance ? suppose I have a subsubdoc array embedded within a subdoc array in a doc, how to query for the id of a subsubdoc ? – Nelson La Rocca Apr 14 '18 at 19:10
  • 1
    `$elemMatch` match conditions within the same nested document, while dot notation match conditions on all nested documents. So if you want to check if a particular **nested document** has both `warehouse: "A"` & `qty: 5` present, then you need to use `$elemMatch`. If you use dot notation instead, it will check in **all documents** that satisfies the condition. So check is not restricting to single nested document. Hope u understood. – Rahul Raj Apr 14 '18 at 19:11
  • 1
    @NelsonLaRocca thats going to be something like `"a.b":{$elemMatch:{c:"test", d:"test"}}` – Rahul Raj Apr 14 '18 at 19:14
  • Thanks a lot Rahul. I think MongoDB should go deeper in their docs about this topic. Thanks again. – Nelson La Rocca Apr 14 '18 at 19:55