Note
This page describes regular expression search capabilities for
self-managed (non-Atlas) deployments. For data hosted on MongoDB, MongoDB
also offers an improved full-text search solution,
MongoDB Search, which has its own $regex
operator. To learn more, see $regex
in the MongoDB Search documentation.
Definition
Compatibility
You can use $regex for deployments hosted in the following
environments:
MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: The subscription-based, self-managed version of MongoDB
MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB
Syntax
Use one of the following syntax variations:
{ <field>: { $regex: /pattern/, $options: '<options>' } } { "<field>": { "$regex": "pattern", "$options": "<options>" } } { <field>: { $regex: /pattern/<options> } }
Note
To use $regex with mongodump, enclose the query
document in single quotes ('{ ... }') to ensure it doesn't interact
with the shell.
The query document must be in Extended JSON v2 format (either relaxed or canonical/strict mode), which includes enclosing the field names and operators in quotes. For example:
mongodump -d=sample_mflix -c=movies -q='{"year": {"$regex": "20"}}'
You can also use regular expression objects (/pattern/) to specify
regular expressions:
{ <field>: /pattern/<options> }
For restrictions on syntax use, see $regex vs. /pattern/ Syntax.
The following <options> are available for regular expressions:
Option | Description |
|---|---|
| Case insensitivity to match upper and lower cases. For an example, see Perform Case-Insensitive Regular Expression Match. |
| For patterns that include anchors ( If the pattern has no anchors or if the string value has no
newline characters (for example, |
| "Extended" capability to ignore all white space characters in
the Additionally, it ignores characters in-between and including
an un-escaped hash/pound ( The |
| Allows the dot character ( |
| Unicode option, which is accepted but redundant. UTF is enabled
by default for |
Note
$regex doesn't support the global search modifier g.
Behavior
$regex vs. /pattern/ Syntax
$in Expressions
To include a regular expression in an $in query predicate operator,
you can only use JavaScript regular expression objects (/pattern/ ).
For example:
{ name: { $in: [ /^acme/i, /^ack/ ] } }
You cannot use $regex operator expressions inside an
$in operator.
Implicit AND Conditions for the Field
To include a regular expression in a comma-separated list of query
conditions for the field, use the $regex operator. For example:
{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } } { name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } } { name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }
x and s Options
To use either the x option or s options, you must use the
$regex operator expression with the $options
operator. For example, to specify the i and the s options, you
must use $options for both:
{ name: { $regex: /acme.*corp/, $options: "si" } } { name: { $regex: 'acme.*corp', $options: "si" } }
PCRE Versus JavaScript
To use PCRE-supported features in a regular expression that
aren't supported in JavaScript, use the $regex operator and
specify the pattern as a string.
To match case-insensitive strings:
"(?i)"begins a case-insensitive match."(?-i)"ends a case-insensitive match.
For example, the regular expression "(?i)a(?-i)cme" matches strings
that:
Begin with
"a"or"A". This is a case-insensitive match.End with
"cme". This is a case-sensitive match.
These strings match the example regular expression:
"acme""Acme"
The following example uses the $regex operator to find name
field strings that match the regular expression "(?i)a(?-i)cme":
{ name: { $regex: "(?i)a(?-i)cme" } }
Starting in version 6.1, MongoDB uses the PCRE2 (Perl Compatible Regular Expressions) library to implement regular expression pattern matching. To learn more about PCRE2, see the PCRE Documentation.
$regex and $not
The $not operator can perform a logical NOT
operation on both:
Regular expression objects (
/pattern/)For example:
db.inventory.find( { item: { $not: /^p.*/ } } ) $regexoperator expressionsFor example:
db.inventory.find( { item: { $not: { $regex: "^p.*" } } } ) db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )
Index Use
Index use and performance for $regex queries depends on
whether the query is case-sensitive or case-insensitive.
Case-Sensitive Queries
For case sensitive regular expression queries, if an index exists for the field, then MongoDB matches the regular expression for the values in the index. This can be faster than a collection scan.
Further optimization can occur if the regular expression is a "prefix expression", which means that all potential matches start with the same string. This allows MongoDB to construct a "range" from that prefix and only match values from the index within the specified range.
A regular expression is a "prefix expression" if it starts with a caret
(^) or a left anchor (\A), followed by a string of simple
symbols. For example, the regex /^abc.*/ is optimized to
match only the values from the index that start with abc.
Additionally, although /^a/, /^a.*/, and /^a.*$/ match
equivalent strings, they have different performance characteristics.
All of these expressions use an index if an appropriate index
exists. However, /^a.*/, and /^a.*$/ are slower. /^a/
can stop scanning after matching the prefix.
Case-Insensitive Queries
Case-insensitive indexes do not improve performance for
$regex queries, as the $regex operator is not collation-aware
and therefore cannot take advantage of such indexes.
Examples
The examples in this section use the following products collection:
db.products.insertMany( [ { _id: 100, sku: "abc123", description: "Single line description." }, { _id: 101, sku: "abc789", description: "First line\nSecond line" }, { _id: 102, sku: "xyz456", description: "Many spaces before line" }, { _id: 103, sku: "xyz789", description: "Multiple\nline description" }, { _id: 104, sku: "Abc789", description: "SKU starts with A" } ] )
Perform a LIKE Match
The following example matches all documents where the sku field is
like "%789":
db.products.find( { sku: { $regex: /789$/ } } )
The example is similar to the following SQL LIKE statement:
SELECT * FROM products WHERE sku like "%789";
Example output:
[ { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 103, sku: 'xyz789', description: 'Multiple\nline description' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
Perform Case-Insensitive Regular Expression Match
The following example uses the i option to perform a
case-insensitive match for sku values that start with ABC:
db.products.find( { sku: { $regex: /^ABC/i } } )
Example output:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
Match Whole Words Only
Use the \b word boundary anchor to match whole words only. A word
boundary matches the position between a word character and a non-word
character, or at the start or end of a string.
The following example matches documents where the description field
contains the word line as a complete word, but not as part of another
word like multiline:
db.products.find( { description: { $regex: /\bline\b/ } } )
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 102, sku: 'xyz456', description: 'Many spaces before line' } ]
MongoDB does not return the document with _id: 103 because its description field
contains line only as part of the word Multiple\nline.
The \n (newline) acts as a word boundary for the second occurrence.
Note
For matching word boundaries with UTF-8 characters, see Extend Regex Options to Match Characters Outside of ASCII.
Multiline Match for Lines Starting with Specified Pattern
The following example uses the m option to match lines starting
with the letter S for multiline strings:
db.products.find( { description: { $regex: /^S/, $options: 'm' } } )
Example output:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
Without the m option, the example output is:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
If the $regex pattern doesn't contain an anchor, the pattern
matches against the whole string. For example:
db.products.find( { description: { $regex: /S/ } } )
Example output:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
Use the . Dot Character to Match New Line
The following example uses the s option to allow the dot character
(.) to match all characters including new line, and the
i option to perform a case-insensitive match:
db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )
Example output:
[ { _id: 102, sku: 'xyz456', description: 'Many spaces before line' }, { _id: 103, sku: 'xyz789', description: 'Multiple\nline description' } ]
Without the s option, the query returns:
[ { _id: 102, sku: 'xyz456', description: 'Many spaces before line' } ]
Ignore White Spaces in Pattern
The following example uses the x option ignore white spaces and the
comments, denoted by the # and ending with the \n in the
matching pattern:
var pattern = "abc #category code\n123 #item number" db.products.find( { sku: { $regex: pattern, $options: "x" } } )
Example output:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' } ]
Use a Regular Expression to Match Case in Strings
The following example uses the regular expression "(?i)a(?-i)bc" to
match sku field strings that contain:
"abc""Abc"
db.products.find( { sku: { $regex: "(?i)a(?-i)bc" } } )
Example output:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
Extend Regex Options to Match Characters Outside of ASCII
New in version 6.1.
By default, some regex options (such as /b and /w) only
recognize ASCII characters. This can cause unexpected results when
performing regex matches against UTF-8 characters.
Starting in MongoDB 6.1, you can specify the *UCP regex option to
match UTF-8 characters.
Important
Performance of UCP Option
The *UCP option results in slower queries than those without the
option specified because *UCP requires a multistage table lookup
to perform the match.
For example, consider the following documents in a songs
collection:
db.songs.insertMany( [ { _id: 0, "artist" : "Blue Öyster Cult", "title": "The Reaper" }, { _id: 1, "artist": "Blue Öyster Cult", "title": "Godzilla" }, { _id: 2, "artist" : "Blue Oyster Cult", "title": "Take Me Away" } ] )
The following regex query uses the \b option in a regex match. The
\b option matches a word boundary.
db.songs.find( { artist: { $regex: /\byster/ } } )
Example output:
[ { _id: 0, artist: 'Blue Öyster Cult', title: 'The Reaper' }, { _id: 1, artist: 'Blue Öyster Cult', title: 'Godzilla' } ]
The previous results are unexpected because none of the whole words in the
returned artist fields begin with the matched string (yster).
The Ö character in documents _id: 0 and _id: 1 is ignored
when performing the match because Ö is a UTF-8 character.
The expected result is the query doesn't return any documents.
To allow the query to recognize UTF-8 characters, specify the *UCP
option before the pattern:
db.songs.find( { artist: { $regex: "(*UCP)/\byster/" } } )
The previous query doesn't return any documents, which is the expected
result because none of the whole words in the artist fields begin with the
string yster.
Tip
Escape Characters for Regex Patterns
When specifying *UCP or any other regular expression option,
use the correct escape characters for your shell or
driver.