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 RegEx type or a plain string
  • Extracts the pattern string and optional flags
  • Validates that options are not specified in both the $options field and the BSON RegEx object 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 via hasConstantRegex() 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 $regex operator accepts plain strings as patterns, enabling runtime variables without special syntax
  • The server processes string variables through extractRegexAndOptions() in src/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →