Skip to content

Querying & Filtering

Evaluation Operators

$regex and $expr: pattern matching and comparing fields to each other.

IntermediateAbout 5 minutes

Two operators you will actually write: `$regex` for strings, `$expr` when the condition must use another field (or an expression), not a constant.

db.users.find({ name: { $regex: /^Rahul/ } })

db.users.find({
  city: { $regex: "bang", $options: "i" }
})
Name starts with R, case-insensitive. Keep the pattern tight.

A leading wildcard (/.*/ or /bang/) cannot use an index the way a prefix can. For 'equals Bangalore' use equality, not regex. $options: "i" is case-insensitive; it is also harder on indexes. Reach for regex for search-ish UI, not for city.

// Compares price to the string "$stock" — almost never what you want
db.products.find({ price: { $gte: "$stock" } })

db.products.find({
  $expr: { $gte: ["$price", "$stock"] }
})
Wrong: $gt against another field's name as a string. Right: $expr.
{ name: "Mechanical Keyboard", price: 4500, stock: 20 }
Keyboard: price 4500, stock 20 — 4500 ≥ 20, so it matches

$expr uses aggregation expression syntax: field paths are "$price". You can $gt, $subtract, $year on a date — the expressions module goes deeper. In a filter, the usual reason is field vs field, or a computed value you do not want to store.

Interview question

When do you need $expr instead of a normal comparison operator?

Think about it first.

Interview question

Why not use $regex for every string filter?

Think about it first.