MongoDB Starts With Query

Tahseen Tauseef Jan 30, 2023 May 04, 2022
  1. MongoDB Starts With Query Using $regex
  2. . Dot Character to Match New Line
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:

  1. regular expression objects (i.e. /pattern/)

For example:

db.inventory.find( { item: { $not: /^p.*/ } } )
  1. $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." }