Logical Operators: $and, $or, $nor, $not
"Cheap or out of stock", "neither sci-fi nor running low", "price not above 8". Once questions combine conditions with or, nor and not, you need MongoDB's logical operators. The good news: you already use AND without writing it.
The rule
Commas already AND; $or any, $nor none, $not flips one field.
| _id | title | year | price | stock | genres |
|---|---|---|---|---|---|
| 1 | Dune | 1965 | 9.99 | 12 | sci-fi, classic |
| 2 | Neuromancer | 1984 | 8.5 | 0 | sci-fi, cyberpunk |
| 3 | Emma | 1815 | 4.25 | 7 | classic, romance |
| 4 | The Hobbit | 1937 | 7.99 | 3 | fantasy, classic, adventure |
| 5 | Circe | 2018 | 12 | 5 | fantasy, myth |
db.books.find({ $or: [ { price: { $lt: 5 } }, { stock: 0 } ] }) // Emma, Neuromancer
db.books.find({ $nor: [ { genres: "sci-fi" }, { stock: { $lt: 5 } } ] }) // Emma, Circe
db.books.find({ price: { $not: { $gt: 8 } } }) // Emma, The Hobbit- Implicit AND:
{ genres: "classic", stock: { $gt: 5 } }needs both. $ortakes an array of condition documents; a document matches if any holds.$nortakes an array; a document matches if none holds, and like$ne, missing fields count as "does not hold".$notis different: it sits inside a field and negates that field's operator.{ price: { $not: { $gt: 8 } } }means "price is not above 8", which also includes documents with noprice.- Explicit
$andis needed when the same key must appear twice, most often two separate$orgroups:
db.books.find({ $and: [
{ $or: [ { genres: "sci-fi" }, { genres: "fantasy" } ] },
{ $or: [ { stock: 0 }, { price: { $gt: 10 } } ] }
] }) // Neuromancer, CirceThe shortcut
For $or and $nor, run each condition alone, then combine the result lists: union for $or, "everything not in the union" for $nor.
First condition alone
genres: "sci-fi"→ Dune, Neuromancer.
The trap: two $or keys in one filter object. The second silently replaces the first, just like a repeated field name; wrap them in $and.
Drills
Answer fast — trust the rule.
How many books match { $or: [ { price: { $lt: 5 } }, { stock: 0 } ] }?
Where does $not go?
Which books match { $nor: [ { genres: "fantasy" }, { price: { $gt: 9 } } ] }?
When do you need an explicit $and?
Remember
- Commas already AND; $or any, $nor none, $not flips one field.
- Shortcut: run each condition alone, then union for
$or, complement for$nor. - Trap: repeated keys like two
$oroverwrite each other; wrap them in$and.
