Regex and Evaluation

Evaluation Operators and Regular Expressions

Evaluation operators run a computation instead of comparing a value.

Evaluation operators
Operator Use it for
$regex pattern matching on strings (PCRE2 syntax)
$expr aggregation expressions, including field-to-field comparisons
$mod [divisor, remainder] arithmetic tests
$jsonSchema validating document shape inside a query
$text tokenized search through a text index (Text Search)
$where server-side JavaScript; deprecated since MongoDB 8.0 1,815

A regular expression literal is a value like any other, so { title: /^The/ } needs no operator; the $regex form exists for a pattern held in a variable and for the x and s options, which a JavaScript literal cannot carry. $expr opens the aggregation expression language inside find(): the only way to compare two fields of one document, and a practical way around bad data.

Patterns, field-to-field comparison, and a type coercion
db.books.find({ title: /^The/ }, { title: 1, _id: 0 })
db.books.find({ 'author.name': { $regex: 'gibson', $options: 'i' } }, { title: 1, _id: 0 })
db.books.find({ $expr: { $gt: [{ $size: '$editions' }, 1] } }, { title: 1, _id: 0 })
db.books.find({ $expr: { $lt: [{ $toDouble: '$price' }, 12] } }, { title: 1, price: 1, _id: 0 })
Output
[ { title: 'The Hobbit' } ]
[ { title: 'Neuromancer' } ]
[ { title: 'Dune' }, { title: 'The Hobbit' }, { title: 'Project Hail Mary' } ]
[
  { title: 'Neuromancer', price: 9.5 },
  { title: 'Snow Crash', price: '11.25' }
]

Only a prefix-anchored, case-sensitive pattern uses an index as a range: /^The/ scans the entries beginning with The, while /Hobbit/ or anything with the i flag scans every entry — and a collation index does not help, because $regex is not collation-aware. For stemming, stop words and relevance, use a text index (Text Search).

The last query finally catches Snow Crash, because $toDouble converts before comparing. That conversion runs per document, so no index serves the predicate: fine as an audit, wrong as a hot path. Fix the data and keep it fixed with $jsonSchema, a collection validator (Evolving Schemas) that doubles as a query — countDocuments({ $jsonSchema: { properties: { price: { bsonType: 'double' } } } }) counts the documents that conform, and the same schema wrapped in $nor lists the offenders.