Logical Operators: $and, $or, $nor, and $not
MongoDB supports logical operators for combining or negating query conditions.
$and
$and matches documents that satisfy every condition in the supplied array.
db.products.find({
$and: [
{ price: { $gte: 1000 } },
{ stock: { $gt: 0 } }
]
});
This selects products priced at least 1000 that also have positive stock.
MongoDB often allows implicit AND when multiple conditions are expressed as separate fields in the same filter:
db.products.find({
price: { $gte: 1000 },
stock: { $gt: 0 }
});
The explicit form is useful when necessary to express multiple conditions involving the same field or more complicated logical structures.
$or
$or matches documents satisfying at least one condition.
db.products.find({
$or: [
{ category: "books" },
{ price: { $lt: 500 } }
]
});
A product matches if it is a book, costs less than 500, or satisfies both conditions.
$nor
$nor matches documents that fail all listed query expressions.
db.products.find({
$nor: [
{ category: "electronics" },
{ stock: { $lt: 1 } }
]
});
This excludes documents matching either listed condition. Missing fields can affect how individual expressions evaluate, so inspect the intended behavior for optional fields.
$not
$not is a field-level operator used to negate the result of another operator or regular expression.
db.products.find({
price: { $not: { $gt: 1000 } }
});
This matches documents for which the price does not satisfy the greater-than condition, including some documents where the field is missing. It is not always interchangeable with $lte.
Combine logical and comparison operators
db.products.find({
$or: [
{
category: "electronics",
price: { $lt: 5000 }
},
{
category: "books",
stock: { $gt: 0 }
}
]
});
Each object inside $or can contain multiple conditions. Those conditions are combined with AND within that object, while the outer $or requires at least one object to match.
Practical query design
Before using nested logical operators, write the requirement in plain language. Then translate each condition into a filter and verify it against a small dataset.
db.logicalDemo.insertMany([
{ name: "Keyboard", category: "electronics", price: 1500, stock: 10 },
{ name: "Book", category: "books", price: 400, stock: 5 },
{ name: "Monitor", category: "electronics", price: 8000, stock: 0 },
{ name: "Notebook", category: "stationery", price: 100, stock: 20 }
]);
// AND: both conditions must match.
db.logicalDemo.find({
price: { $gte: 500 },
stock: { $gt: 0 }
});
// OR: either condition can match.
db.logicalDemo.find({
$or: [
{ category: "books" },
{ price: { $lt: 500 } }
]
});
// NOR: exclude documents matching either expression.
db.logicalDemo.find({
$nor: [
{ category: "electronics" },
{ stock: { $lt: 1 } }
]
});- $and requires every listed condition to match.
- $or requires at least one listed condition to match.
- $nor excludes documents matching any listed condition.
- $not negates a field-level query expression and is not always equivalent to a simpler comparison operator.
- Nested conditions within one $or branch are combined with AND.
In an $or array, what happens when one condition object contains both `category: "books"` and `stock: { $gt: 0 }`?