Arrays & Nested Documents
$elemMatch
When array conditions must hold on the same element — the distinction interviews keep asking about.
$elemMatch says: one element of the array must satisfy all of these conditions. Same order as the last lesson. Same trap. This is the fix.
{
userId: ObjectId("64a1b2c3d4e5f6a7b8c90001"),
amount: 4900,
status: "completed",
items: [
{ name: "Mechanical Keyboard", quantity: 1, unitPrice: 4500 },
{ name: "USB-C Cable", quantity: 2, unitPrice: 200 }
]
}Any elements (dotted)
- items.unitPrice > 500 (keyboard)
- items.quantity = 2 (cable)
- Order matches — probably wrong
Same element ($elemMatch)
- One line: unitPrice > 500 AND quantity 2
- This order does not match
- A 2× keyboard at ₹4500 would
db.orders.find({
items: {
$elemMatch: {
unitPrice: { $gt: 500 },
quantity: 2
}
}
})You do not need $elemMatch for a single condition: { "items.name": "USB-C Cable" } is enough. You need it when two or more conditions must share an element. You also need it for a single complex operator on one element that would otherwise be ambiguous — { items: { $elemMatch: { quantity: { $gte: 2 } } } } is valid, though { "items.quantity": { $gte: 2 } } already means 'some element'.
db.orders.find(
{ items: { $elemMatch: { name: "USB-C Cable" } } },
{ _id: 0, amount: 1, items: { $elemMatch: { name: "USB-C Cable" } } }
)Interview question
How do you query a nested field, and how do you match inside an array of objects?
Embedded object: dot notation. Array of objects: a dotted path is 'any element'. When every condition must hold on the same element, use $elemMatch. That is the usual line-item interview question.
Walk through two line items — expensive qty 1, cheap qty 2 — and show why the dotted AND is wrong.