Gotcha 1: Implicit AND Silent Key Overwrite
The most common MongoDB beginner bug. Two conditions targeting the same field as separate JS object keys — the second silently overwrites the first before the query ever reaches MongoDB.
db.products.find({ price: { $gt: 100 }, price: { $lt: 500 } })
db.products.find({
$and: [{ price: { $gt: 100 } }, { price: { $lt: 500 } }]
})
db.products.find({ price: { $gt: 100, $lt: 500 } })
Gotcha 2: $not with a Plain Value
db.users.find({ status: { $not: "active" } })
db.users.find({ status: { $ne: "active" } })
Gotcha 3: $or Index Union — Each Branch Needs Its Own Index
db.users.find({ $or: [{ city: "Mumbai" }, { role: "admin" }] })
db.users.createIndex({ city: 1 })
db.users.createIndex({ role: 1 })
db.users.find({ $or: [{ city: "Mumbai" }, { role: "admin" }] })
.explain("executionStats")
Gotcha 4: Empty Arrays Throw Errors
ERROR
Passing an empty array to $and, $or, or $nor throws a BadValue error. Always ensure at least one condition exists before querying.
db.col.find({ $and: [] })
db.col.find({ $or: [] })
db.col.find({ $nor: [] })
const conditions = []
if (filterCity) conditions.push({ city: filterCity })
if (filterRole) conditions.push({ role: filterRole })
const query = conditions.length > 0
? { $or: conditions }
: {}
db.users.find(query)
Gotcha 5: $nor Includes Docs with Absent Fields
db.users.find({ $nor: [{ status: "banned" }] })
db.users.find({
status: { $exists: true },
$nor: [{ status: "banned" }]
})
Nested Operators: $and with $or Inside
db.users.find({
$and: [
{ verified: true },
{ accountAge: { $gte: 30 } },
{
$or: [
{ role: "admin" },
{ city: "Mumbai" }
]
}
]
})
db.users.find({
verified: true,
accountAge: { $gte: 30 },
$or: [
{ role: "admin" },
{ city: "Mumbai" }
]
})
db.users.find({
$and: [
{ $or: [{ city: "Mumbai" }, { city: "Delhi" }] },
{ $or: [{ role: "admin" }, { role: "manager" }] }
]
})
TIP
You can only have one $or key at the top level of a filter object (JS key uniqueness). To combine two separate $or groups, wrap them in an explicit $and: [ {$or:[...]}, {$or:[...]} ].