Comparison Operators
Beyond simple field-equals-value matching, MongoDB provides comparison operators such as $gt, $gte, $lt, $lte, and $ne that filter on ranges and inequalities. { price: { $gte: 20, $lte: 100 } } finds documents where price falls within an inclusive range, and $in / $nin let you match against a set of possible values in a single condition instead of chaining multiple $or clauses.
Cricket analogy: It is like filtering a stats database for batters with a strike rate between 130 and 160 in T20s — $gte and $lte together carve out a precise performance band instead of an exact single value.
Logical Operators: $and, $or, $not, $nor
MongoDB implicitly ANDs top-level fields in a filter object, so { inStock: true, price: { $lt: 50 } } already requires both conditions. Explicit $and is needed when you must apply multiple conditions to the same field, such as price greater than 10 and less than 100. $or takes an array of condition objects and matches documents satisfying at least one, while $not negates a single operator expression and $nor matches documents that fail every clause.
Cricket analogy: It is like a selector requiring a player who bats AND bowls, versus one who is either a specialist opener OR a death-overs bowler — implicit AND stacks conditions, while $or widens the net to either path.
Element and Array Operators
$exists: true/false checks whether a field is present regardless of its value, useful for finding documents with optional fields set or missing. $type checks a field's BSON type. For array fields, $elemMatch requires at least one array element to satisfy multiple conditions simultaneously — without it, conditions on an array field can each match a different element, which is often not what you want when checking, for example, a review with both a high score and a specific tag.
Cricket analogy: It is like scouting for a player whose profile even has a 'captaincy experience' field filled in, versus one whose record lacks it entirely — $exists checks presence, not value, the way a selector checks whether that data point was ever recorded.
// Products priced between 20 and 100, tagged either electronics or accessories
db.products.find({
price: { $gte: 20, $lte: 100 },
tags: { $in: ["electronics", "accessories"] }
});
// A single review array element with both a rating >= 4 and verified: true
db.products.find({
reviews: { $elemMatch: { rating: { $gte: 4 }, verified: true } }
});
// Documents where discountCode exists and is not null
db.products.find({ discountCode: { $exists: true, $ne: null } });Without $elemMatch, a filter like { "reviews.rating": { $gte: 4 }, "reviews.verified": true } can match a document even if no single review satisfies both conditions — one review could have rating 5 while a different review is verified. $elemMatch forces both conditions onto the same array element.
Regex and Text Matching
The $regex operator (or a native regex literal like /pattern/i) matches string fields against a pattern, useful for case-insensitive partial matches such as searching product names. Unlike a text index search with $text, a $regex query that isn't anchored with a leading ^ cannot use a standard index efficiently and typically falls back to a collection scan, so it should be reserved for smaller collections or combined with other indexed filters.
Cricket analogy: It is like scanning every player's name in a database for any player whose name contains 'kumar' anywhere, versus looking up an exact indexed name — the flexible search is powerful but slower across a huge roster.
Unanchored regex queries (no leading ^) generally cannot use an index efficiently and force a full collection scan, which becomes a serious performance problem on large collections. For real full-text search, use a dedicated text index with $text or an external search engine rather than $regex.
- Comparison operators like $gt, $gte, $lt, $lte, $ne, $in, and $nin filter on ranges and value sets.
- Top-level fields in a filter object are implicitly ANDed; explicit $and is needed for multiple conditions on the same field.
- $or matches documents satisfying at least one of several condition objects; $nor matches none of them.
- $exists checks field presence regardless of value; $type checks a field's BSON type.
- $elemMatch requires a single array element to satisfy multiple conditions at once.
- Without $elemMatch, separate conditions on an array field can each be satisfied by different elements.
- Unanchored $regex queries typically cannot use an index and fall back to a collection scan.
Practice what you learned
1. Which operator would you use to find products priced strictly between 10 and 50?
2. Why is $elemMatch needed when querying an array of subdocuments for two conditions together?
3. What does { field: { $exists: true } } match?
4. Are top-level fields in a MongoDB filter object combined with AND or OR by default?
5. Why should unanchored $regex queries be used cautiously on large collections?
Was this page helpful?
You May Also Like
Querying Documents
Learn how to retrieve documents from MongoDB collections using find() and findOne(), filters, projections, and cursor methods.
Updating Documents
Learn how to modify existing documents using updateOne, updateMany, replaceOne, update operators like $set and $inc, and upserts.
Deleting Documents
Learn how to remove documents from MongoDB collections with deleteOne and deleteMany, and how to safely drop entire collections.