AND and OR Conditions
Master logical operators in MongoDB — $and, $or, $not, and $nor. Learn how to combine multiple conditions, build complex queries with nested logic, and understand implicit vs explicit AND operations.
Real-world queries rarely have just one condition. You'll often need to combine multiple filters — find users who are developers AND over 25, or products that are in electronics OR books categories. MongoDB provides four logical operators: $and, $or, $not, and $nor.
Implicit AND
When you pass multiple fields in a query filter, MongoDB treats them as AND conditions:
// Implicit AND — both conditions must be true
db.users.find({
role: "developer",
age: { $gt: 25 }
})
// Equivalent to: WHERE role = 'developer' AND age > 25
Explicit $and
Use $and when you need multiple conditions on the same field, or for clarity:
// Multiple conditions on the same field
db.products.find({
$and: [
{ price: { $gte: 100 } },
{ price: { $lte: 500 } }
]
})
// Products priced between 100 and 500
// This is equivalent (and shorter):
db.products.find({
price: { $gte: 100, $lte: 500 }
})
You MUST use explicit $and when you have multiple conditions with the same operator on the same field:
// Find products in "electronics" that are also NOT "refurbished"
db.products.find({
$and: [
{ category: "electronics" },
{ category: { $ne: "refurbished" } }
]
})
$or — Match Any Condition
// Find developers OR designers
db.users.find({
$or: [
{ role: "developer" },
{ role: "designer" }
]
})
// Note: For same-field "in" queries, $in is simpler:
db.users.find({ role: { $in: ["developer", "designer"] } })
// Find products that are cheap OR highly rated
db.products.find({
$or: [
{ price: { $lt: 100 } },
{ rating: { $gte: 4.5 } }
]
})
Combining $and with $or
// Find active users who are either developers or designers
db.users.find({
isActive: true,
$or: [
{ role: "developer" },
{ role: "designer" }
]
})
// SQL: WHERE isActive = true AND (role = 'developer' OR role = 'designer')
// Complex: (category is electronics AND price > 500) OR (category is books AND rating > 4)
db.products.find({
$or: [
{
$and: [
{ category: "electronics" },
{ price: { $gt: 500 } }
]
},
{
$and: [
{ category: "books" },
{ rating: { $gt: 4 } }
]
}
]
})
$not — Negate a Condition
// Find users whose age is NOT greater than 30
db.users.find({
age: { $not: { $gt: 30 } }
})
// This matches age <= 30 AND documents without the age field
// Find names that do NOT start with "A"
db.users.find({
name: { $not: /^A/ }
})
// $not vs $ne:
// $ne excludes a specific value
db.users.find({ role: { $ne: "admin" } })
// $not negates an entire expression
db.users.find({ age: { $not: { $gte: 18 } } }) // age < 18 or no age field
$nor — None of the Conditions
$nor returns documents that fail ALL specified conditions:
// Find users who are neither developers nor managers
db.users.find({
$nor: [
{ role: "developer" },
{ role: "manager" }
]
})
// Find inactive users with no recent login
db.users.find({
$nor: [
{ isActive: true },
{ lastLogin: { $gte: new Date("2024-01-01") } }
]
})
Real-World Examples
E-commerce Product Search
// Products in stock, priced 500-5000, in electronics or gadgets
db.products.find({
inStock: true,
price: { $gte: 500, $lte: 5000 },
$or: [
{ category: "electronics" },
{ category: "gadgets" }
]
})
User Activity Report
// Users who are active AND (logged in this month OR have orders this month)
db.users.find({
isActive: true,
$or: [
{ lastLogin: { $gte: new Date("2024-12-01") } },
{ lastOrderDate: { $gte: new Date("2024-12-01") } }
]
})
Content Moderation
// Posts that are reported AND (have more than 5 reports OR are from banned users)
db.posts.find({
isReported: true,
$or: [
{ reportCount: { $gt: 5 } },
{ "author.isBanned": true }
]
})
Operator Summary
// $and — ALL conditions must match
// Implicit: { field1: val1, field2: val2 }
// Explicit: { $and: [ {cond1}, {cond2} ] }
// $or — ANY condition must match
// { $or: [ {cond1}, {cond2} ] }
// $not — Negates a single condition
// { field: { $not: { operator: value } } }
// $nor — NONE of the conditions must match
// { $nor: [ {cond1}, {cond2} ] }
What's Next
You can now build complex multi-condition queries. In the next episode, we'll learn how to update existing documents using updateOne(), updateMany(), and various update operators like $set, $inc, $push, and $pull.