How to Use a MongoDB Regex Query with a String Variable: A Complete Guide
MongoDB's query engine accepts regular expression patterns as plain strings in the $regex operator, allowing runtime variables to be compiled and executed server-side without requiring literal regex syntax.
When working with the mongodb/mongo source code, you'll find that the $regex operator is designed to handle dynamic patterns stored in variables. Unlike some database systems that require regex literals at parse time, MongoDB's architecture separates pattern extraction, compilation, and execution, enabling flexible string-based mongodb regex query operations across all official drivers.
How MongoDB Processes String-Based Regex Patterns
The server-side implementation in src/mongo/db/exec/expression/evaluate_regex.cpp handles string variables through a three-phase pipeline that validates, compiles, and executes regular expressions at runtime.
Pattern Extraction and Validation
When a mongodb regex query receives a string variable rather than a BSON RegEx object, the extractRegexAndOptions() function (lines 93-130) performs the initial validation:
- Accepts either a BSON
RegExtype or a plain string - Extracts the pattern string and optional flags
- Validates that options are not specified in both the
$optionsfield and the BSONRegExobject simultaneously (error 51107)
This validation ensures that runtime string variables are treated with the same safety checks as literal regex patterns.
Server-Side Compilation
The compile() function (lines 136-156) transforms the extracted string into a pcre::Regex object:
- Builds the compiled regex using the pattern and options
- Caches the compiled object when the regex is constant (literal patterns)
- Rebuilds the compiled object for each execution when the pattern is a runtime variable
This distinction is critical for performance: string variables prevent regex caching, while literal patterns allow the server to reuse compiled objects across query executions.
Query Execution
The execute() and nextMatch() functions (lines 250-284) perform the actual pattern matching:
- Iterates through input strings using the compiled PCRE object
- Handles multiline and global match semantics based on options
- Returns boolean match results or extracted capture groups
MongoDB Regex Query Syntax for String Variables
MongoDB Shell Examples
When using the shell, you can pass string variables directly to the $regex operator:
// Define pattern at runtime
var pattern = '^A.*';
var options = 'i'; // case-insensitive
// Use in find query
db.products.find({
sku: { $regex: pattern, $options: options }
});
The driver sends { sku: { $regex: "^A.*", $options: "i" } } to the server, where extractRegexAndOptions() processes the string variables.
Aggregation Pipeline with $regexMatch
For complex aggregations, use $regexMatch inside $expr to evaluate string variables:
var datePattern = '202[0-9]-[01][0-9]-[0-3][0-9]$';
db.sales.aggregate([
{
$match: {
$expr: {
$regexMatch: {
input: "$orderDate",
regex: datePattern,
options: "i"
}
}
}
}
]);
This follows the same server-side path through evaluate_regex.cpp, allowing runtime pattern evaluation against document fields.
Node.js Driver Implementation
const { MongoClient } = require('mongodb');
async function searchLogs() {
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const collection = client.db('test').collection('logs');
// Pattern from user input or configuration
const pattern = '^ERROR.*';
const cursor = collection.find({
message: { $regex: pattern, $options: 's' }
});
const results = await cursor.toArray();
console.log(results);
await client.close();
}
Python (PyMongo) Dynamic Patterns
from pymongo import MongoClient
client = MongoClient()
db = client.mydb
# Generate patterns dynamically
keywords = ['login', 'signup', 'checkout']
regexes = [f'{kw}\\b' for kw in keywords]
for pattern in regexes:
for doc in db.events.find({'event': {'$regex': pattern, '$options': 'i'}}):
print(doc)
Performance Considerations and Best Practices
Regex Caching vs. Runtime Compilation
According to the implementation in src/mongo/db/exec/expression/evaluate_regex.cpp, MongoDB distinguishes between constant and variable regex patterns:
- Literal patterns (e.g.,
/^foo/or{ $regex: "^foo" }with string literals) are cached viahasConstantRegex()and reused across executions - String variables force recompilation on each execution, increasing CPU overhead
When performance is critical, prefer literal regex syntax over string variables, or ensure your application caches query plans.
Index Utilization
The src/mongo/db/query/analyze_regex.cpp file contains logic that determines whether a regex can use an index prefix. String variables follow the same analysis path as literals:
- Anchored patterns starting with
^can use indexes - Case-insensitive queries may require different index strategies
- The analysis runs at query planning time, treating string variables as opaque patterns
Options Handling Validation
The server raises error 51107 if you supply options in both the $options field and a BSON RegEx object simultaneously. When using string variables, always use the $options field rather than embedding flags in the pattern string:
// Correct
{ $regex: pattern, $options: 'i' }
// Avoid (if pattern contains embedded flags)
{ $regex: '/^test/i' }
Summary
- MongoDB's
$regexoperator accepts plain strings as patterns, enabling runtime variables without special syntax - The server processes string variables through
extractRegexAndOptions()insrc/mongo/db/exec/expression/evaluate_regex.cpp, compiling them into PCRE objects at execution time - String variables prevent regex caching, while literal patterns allow the server to reuse compiled objects via
hasConstantRegex() - All official drivers (Node.js, Python, Java) serialize string variables identically to the server, using the
{ $regex: pattern, $options: flags }syntax - Index usage for string-based regex patterns is analyzed in
src/mongo/db/query/analyze_regex.cpp, supporting anchored patterns (^) regardless of whether the pattern is a variable or literal
Frequently Asked Questions
Can I use a JavaScript RegExp object directly in the MongoDB shell with a variable pattern?
No, you should pass the pattern as a string to the $regex field. While the shell supports BSON RegEx literals like /^pattern/, when your pattern is stored in a variable, use { $regex: myVariable } rather than trying to construct a RegExp object. The server in src/mongo/db/exec/expression/evaluate_regex.cpp extracts the string value and compiles it server-side.
Why does my regex query run slower when I use a string variable instead of a literal pattern?
When you use a string variable, MongoDB cannot cache the compiled PCRE object between query executions. According to the implementation in evaluate_regex.cpp, the compile() function checks hasConstantRegex() to determine if the pattern is constant. Literal patterns are compiled once and reused, while variables force recompilation on every document evaluation or query execution, increasing CPU overhead.
How do I pass regex options when using a string variable in Python or Node.js?
Always use the $options field alongside $regex rather than embedding flags in the pattern string. In PyMongo: {'$regex': pattern, '$options': 'i'}. In Node.js: { $regex: pattern, $options: 'i' }. The server validates in extractRegexAndOptions() that you don't specify options in both places simultaneously, which would trigger error 51107.
Can MongoDB use an index for a regex query when the pattern is stored in a variable?
Yes, index usage depends on the pattern structure, not whether it's a literal or variable. The src/mongo/db/query/analyze_regex.cpp module analyzes the pattern to determine if it can use an index prefix. Anchored patterns starting with ^ can use indexes regardless of whether the pattern comes from a variable. However, because the query planner sees string variables as opaque values, it may sometimes be more conservative in index selection compared to known literal patterns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →