Skip to content

Arrays & Nested Documents

Matching Array Elements

Matching any element versus matching the same element — the distinction that makes $elemMatch necessary.

IntermediateAbout 5 minutes

Orders embed items. Each element is a document. A dotted path like items.unitPrice means some element has that field. Two dotted paths mean some element matches the first and some element matches the second — not necessarily the same one.

{
  userId: ObjectId("64a1b2c3d4e5f6a7b8c90001"),
  amount: 4900,
  status: "completed",
  items: [
    { name: "Mechanical Keyboard", quantity: 1, unitPrice: 4500 },
    { name: "USB-C Cable", quantity: 2, unitPrice: 200 }
  ]
}
One order. Keyboard is expensive. Cable has quantity 2.
db.orders.find({
  "items.unitPrice": { $gt: 500 },
  "items.quantity": 2
})
Looks like 'an expensive line with qty 2'. It is not.
{ amount: 4900, items: [ { name: "Mechanical Keyboard", quantity: 1, unitPrice: 4500 }, { name: "USB-C Cable", quantity: 2, unitPrice: 200 } ] }
This order matches — keyboard satisfies price, cable satisfies quantity

There is no line with unitPrice > 500 and quantity: 2. The filter still hits. That is normal array matching: each condition is independent across the array. If that is what you wanted (any expensive item, and separately any qty-2 item), you are done. If you wanted one line item that is both, you need $elemMatch — next lesson.

A single dotted condition is fine: { "items.name": "USB-C Cable" } — at least one item has that name. The bug appears when you AND two conditions on the array of objects.

Interview question

Why can two conditions on an array of objects match different elements?

Think about it first.