Query Operators: Comparison, Logical and Element

intermediate
12 min

Query Operators: Comparison, Logical and Element

Real-world queries need more than exact matches: price ranges, multiple alternatives, missing fields, and combined conditions. MongoDB expresses all of these with query operators, special keys that start with a dollar sign. This CodeYourCraft lesson covers the three operator families you will use daily: comparison, logical, and element operators.

Comparison Operators

Comparison operators wrap the value you are testing against:

javascript
use shop db.products.find({ price: { $gt: 1000 } }) // greater than db.products.find({ price: { $gte: 1000, $lte: 5000 } }) // inclusive range db.products.find({ price: { $ne: 499 } }) // not equal db.products.find({ name: { $in: ['Desk Lamp', 'Webcam 1080p'] } }) db.products.find({ name: { $nin: ['Desk Lamp'] } }) // not in list

The $in operator is especially useful because it replaces a chain of OR conditions with one readable list, and it can even mix types and regular expressions. Note that $ne and $nin also match documents where the field is missing entirely, which sometimes surprises newcomers.

Logical Operators

When implicit AND is not enough, four logical operators combine sub-queries. Each takes an array of filter documents:

javascript
// OR: cheap items or audio gear db.products.find({ $or: [ { price: { $lt: 1000 } }, { tags: 'audio' } ] }) // AND with two conditions on the SAME field db.products.find({ $and: [ { tags: { $ne: 'video' } }, { tags: { $ne: 'audio' } } ] }) // NOR: neither condition may match db.products.find({ $nor: [ { price: { $lt: 500 } }, { tags: 'clearance' } ] }) // NOT negates one operator expression db.products.find({ price: { $not: { $gt: 5000 } } })

You only need explicit $and when you must apply the same field or operator twice in one filter; otherwise listing fields side by side is cleaner. Also note the subtlety that $not and $nor match documents where the field does not exist, because the inner condition cannot be true for a missing field.

Element Operators

Because collections are schemaless, two questions come up constantly: does this field exist, and what type is it?

javascript
// Documents that have (or lack) a discount field db.products.find({ discount: { $exists: true } }) db.products.find({ discount: { $exists: false } }) // Documents where price is stored as a double instead of int db.products.find({ price: { $type: 'double' } }) // Distinguish a null value from a missing field db.products.find({ discount: null }) // null OR missing db.products.find({ discount: { $type: 'null' } }) // only explicit null

The $type operator is a great data-quality audit tool, catching fields that drifted across types as your application evolved.

Combining Everything

Operators compose naturally. Here is a realistic storefront query: in-stock accessories under 5000, excluding clearance items, newest first:

javascript
db.products.find({ tags: 'accessories', price: { $lt: 5000 }, 'stock.warehouse': { $gt: 0 }, clearance: { $exists: false } }).sort({ addedAt: -1 }).limit(20)

Key Takeaways

  • Comparison operators ($gt, $gte, $lt, $lte, $ne, $in, $nin) express ranges and lists.
  • Logical operators ($or, $and, $not, $nor) combine sub-filters; implicit AND covers most cases.
  • $ne, $nin, $not, and $nor also match documents missing the field.
  • $exists tests field presence; $type checks the BSON type and helps audit data quality.
  • Operators nest and combine freely with dot notation, sort, and limit.

Next we switch from reading to modifying data, with updateOne, updateMany, and the update operator family.

Query Operators: Comparison, Logical and Element - MongoDB | CodeYourCraft | CodeYourCraft