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.

Combine logical conditions
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 } }
  ]
});
💡 The examples demonstrate implicit AND, explicit OR, and NOR. Carefully examine the returned documents to see how conditions combine.
Key Takeaways
  • $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.
Knowledge Check

In an $or array, what happens when one condition object contains both `category: "books"` and `stock: { $gt: 0 }`?