Array Operators: $all, $size, $elemMatch
Arrays are where MongoDB queries surprise people most. "A rating by Ben with 5 stars" sounds like one condition, but written the obvious way it matches a book where Ben gave 4 and someone else gave 5. Three operators give you precise control.
The rule
$all: every value present. $size: exact length. $elemMatch: one element passes everything.
The array fields in full:
| title | genres | ratings |
|---|---|---|
| Dune | sci-fi, classic | asha 5, ben 4 |
| Neuromancer | sci-fi, cyberpunk | asha 3 |
| Emma | classic, romance | (empty array) |
| The Hobbit | fantasy, classic, adventure | ben 5, chen 2 |
| Circe | fantasy, myth | (no field) |
db.books.find({ genres: { $all: ["classic", "sci-fi"] } }) // Dune
db.books.find({ genres: { $size: 3 } }) // The Hobbit
db.books.find({ ratings: { $elemMatch: { user: "ben", score: { $gte: 5 } } } }) // The Hobbit$allneeds every listed value somewhere in the array, in any order. Compare the exact match{ genres: ["sci-fi", "classic"] }, which needs that exact array in that order.$sizematches an exact length only. It cannot take a range such as{ $gt: 2 }.$elemMatchrequires one single element to satisfy all its conditions together.
The shortcut
With several conditions on one array, ask "Must the same element pass them all?" If yes, use $elemMatch. Dotted paths let each condition pick its own element.
The dotted way
{ "ratings.user": "ben", "ratings.score": { $gte: 5 } }.
The same effect hits ranges on arrays of numbers: { "ratings.score": { $gt: 2, $lt: 4 } } matches The Hobbit (5 is over 2, 2 is under 4) even though no single score lies between them.
Drills
Answer fast — trust the rule.
How many books match { genres: { $size: 2 } }?
How many books match { genres: ["classic", "sci-fi"] }?
Which books match { ratings: { $elemMatch: { score: { $gt: 2, $lt: 4 } } } }?
Which books match { "ratings.score": { $gt: 2, $lt: 4 } }?
Which filter finds books with exactly zero ratings in their array?
Remember
- $all: every value present. $size: exact length. $elemMatch: one element passes everything.
- Shortcut: must the same element pass every condition? Then
$elemMatch. - Trap: dotted conditions on an array can be satisfied by different elements.
