Query Nested Docs, Arrays & Null
Documents can contain nested objects. Use dot notation to query nested fields — "address.city" matches the city inside an address object.
Embedded and nested documents — dot notation
Documents can contain nested objects. Use dot notation to query nested fields — "address.city" matches the city inside an address object.
Real-life example: Dot notation is like writing 'home address → city' on a form — you drill into a nested level to find the value.
// Sample student document:
// {
// name: "Rahul Sharma",
// address: { city: "Bengaluru", pincode: "560001", state: "Karnataka" },
// guardian: { name: "Mr. Sharma", phone: "9876543210" }
// }
// Students in Bengaluru
db.students.find({ "address.city": "Bengaluru" })
// Students in Karnataka with pincode starting 560
db.students.find({
"address.state": "Karnataka",
"address.pincode": { $regex: "^560" }
})
// Products with supplier in a specific region
db.products.find({ "supplier.country": "IN" })Query arrays — $all, $size, $elemMatch
Arrays store ordered lists. Equality on an array field matches if any element equals the value. Use $all, $size, and $elemMatch for precise array queries.
Real-life example: Querying arrays is like asking 'students who take BOTH Math AND CS' ($all) vs 'students who take Math' (any element match).
// Any student with Mathematics as a subject
db.students.find({ subjects: "Mathematics" })
// $all — document must contain ALL listed values
db.students.find({
subjects: { $all: ["Mathematics", "Computer Science"] }
})
// $size — array must have exactly N elements
db.products.find({ tags: { $size: 3 } })
// $elemMatch — at least one array element matches ALL conditions
db.orders.find({
items: {
$elemMatch: { productName: "Mouse", qty: { $gte: 2 } }
}
})
// Match array of embedded documents
db.students.find({
scores: {
$elemMatch: { subject: "Physics", marks: { $gte: 90 } }
}
})// First element of array (zero-indexed)
db.students.find({ "subjects.0": "Mathematics" })
// Nested array in order items
db.orders.find({ "items.0.category": "electronics" })
// $size does not accept ranges — use $expr for "more than 3 tags"
db.products.find({
$expr: { $gt: [{ $size: { $ifNull: ["$tags", []] } }, 3] }
})Null and missing fields — $exists
In MongoDB, null and missing fields behave differently. { field: null } matches documents where field is null OR field does not exist. Use $exists to distinguish.
Real-life example: $exists is like asking 'Does this form have an email field filled in?' vs 'Is the email blank?' — different questions.
- Use $exists: false in read queries when implementing soft delete filters.
- Schema validation can require fields — but legacy data may still lack them.
- Combine $exists with $type to find fields of unexpected types.
// Matches: field is null OR field is absent
db.students.find({ email: null })
// Field exists (any value including null)
db.students.find({ email: { $exists: true } })
// Field is completely absent
db.students.find({ email: { $exists: false } })
// Field exists AND is explicitly null (not missing)
db.students.find({
email: { $exists: true, $eq: null }
})
// Students missing phone number
db.students.find({ phone: { $exists: false } })
// Products with no discount field (never on sale)
db.products.find({ discount: { $exists: false } })// Find incomplete student profiles
db.students.find({
$or: [
{ email: { $exists: false } },
{ email: null },
{ email: "" }
]
})
// Products missing required category
db.products.find({ category: { $exists: false } })
// Count how many users have no profile photo
db.users.countDocuments({ profilePhotoUrl: { $exists: false } })