MongoDB Starts With Query

In this MongoDB article, the user will learn to start with a query using $regex
. It provides regular expression capabilities for pattern matching strings in queries.
MongoDB Starts With Query Using $regex
If you want to use $regex
, use one of the following syntaxes.
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }
In MongoDB, the user can also use regular expression objects (i.e., /pattern/
) to specify regular expressions.
{ <field>: /pattern/<options> }
The user can use regular expressions with the following <options>
.
Option | Description | Syntax Restrictions |
---|---|---|
i |
Case insensitive to match upper and lower cases. | |
m |
For strings with multi-line values, match at the beginning or end of each line for patterns that include anchors such as ^ at the start and $ at the end. The m option has no effect if the pattern has no anchors or if the string value contains no newline characters (e.g.\n ). |
|
x |
All white space characters in the $regex pattern are ignored unless they are escaped or included in a character class. It also ignores characters in the middle and includes an unescaped hash/pound (# ) character and the following newline, allowing you to add comments in complex patterns. White space characters might not appear within special character sequences in a pattern; this only pertains to data characters. The x option does not affect how the VT character is handled (i.e., code 11). |
It will require $regex with $options syntax |
s |
It allows the dot character (. ) to match any character, including newlines. |
Requires $regex with $options syntax |
The $regex
operator doesn’t support the global search modifier g
.
the $in
Expression
Only JavaScript regular expression objects (i.e., /pattern/
) can be used to incorporate a regular expression in the $in
query expression. Consider the following example.
{ name: { $in: [ /^acme/i, /^ack/ ] } }
Inside the $in
, you can’t utilize $regex
operator expressions.
Implicit AND
Conditions for the Field
Use the $regex
operator to incorporate a regular expression in a comma-separated list of query criteria for the field. Consider the following example.
{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }
the $regex
Operator With x
and s
The user should use the $regex
operator with the $options
operator to use the x
or s
options. For example, to specify the i
and s
options, you must use $options
.
{ name: { $regex: /acme.*corp/, $options: "si" } }
{ name: { $regex: 'acme.*corp', $options: "si" } }
PCRE vs. JavaScript
The user should use the $regex
operator expression with the pattern as a string to leverage PCRE-supported features in the regex pattern that are not supported in JavaScript.
For example, you must use the $regex
operator with the pattern as a string to use (?i)
and (?-i)
in the pattern to turn case-insensitivity on for the remaining pattern.
{ name: { $regex: '(?i)a(?-i)cme' } }
$regex
and $not
Starting from version 4.0.7, the $not
operator can perform a logical NOT
operation on both:
- regular expression objects (i.e.
/pattern/
)
For example:
db.inventory.find( { item: { $not: /^p.*/ } } )
$regex
operator expressions (starting in MongoDB 4.0.7).
For example:
db.inventory.find( { item: { $not: { $regex: "^p.*" } } } )
db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )
In version 4.0.6 and earlier, you could use the $not
operator with regular expression objects (i.e. /pattern/
) but not with the $regex
operator expressions.
If the field has an index, MongoDB checks the regular expression against the values in the index, which can be faster than a collection scan for case-sensitive regular expression queries.
More optimization is possible if the regular expression has a prefix expression, which indicates that all potential matches begin with the exact string. This enables MongoDB to create a range from the prefix and only match against index values within that range.
If a regular expression begins with a caret (^
) or a left anchor (\A
), followed by a string of simple symbols, it is called a prefix expression. For example, the regex /^abc.*/
will be optimized by only matching against index values that begin with abc
.
Furthermore, while /^a/
, /^a.*/
, and /^a.*$/
all match comparable strings, their performance is different.
If a suitable index exists, all of these expressions use it; nevertheless, /^a.*/
and /^a.*$/
are slower. After matching the prefix, /^a/
can stop searching.
Regular expression queries that are case insensitive can’t leverage indexes efficiently. The $regex
implementation, for example, is not collation-aware and hence cannot use case-insensitive indexes.
Examples:
The following examples use a collection called products
with the following documents.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." },
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" },
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" },
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }
the LIKE
Statement
This example matches all documents where the ski
field is like "%789"
.
db.products.find( { ski: { $regex: /789$/ } } )
The example is similar to the following SQL LIKE
statement.
SELECT * FROM products
WHERE ski like "%789";
Case-Insensitive Regular Expression Match
The following example uses the i
option and performs a case-insensitive match for documents with a ski
value that starts with ABC
.
db.products.find( { ski: { $regex: /^ABC/i } } )
The query matches the following documents.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
Multi-Line Match
The m
option is used in the following example to match lines beginning with the letter S
in multi-line strings.
db.products.find( { description: { $regex: /^S/, $options: 'm' } } )
The query matches the following documents given below.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
Without the m
option, the query would only match the following document.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
If the $regex
pattern does not include an anchor, the pattern is applied to the entire string, as in the following example.
db.products.find( { description: { $regex: /S/ } } )
Then, the $regex
would match both documents.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
.
Dot Character to Match New Line
The s
option allows the dot character (.
) to match all characters, including the new line, and the i
option allows for a case-insensitive match.
db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )
The query matches the following documents.
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }
The query would only match the following document without the s
option.
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" }
White Spaces in a Pattern
In the matching pattern, the x
option ignores white spaces and comments denoted by the #
and ends with the n:.
.
var pattern = "abc #category code\n123 #item number"
db.products.find( { ski: { $regex: pattern, $options: "x" } } )
The query matches the following document.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }