> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

# `regex` (MongoDB Search Operator)

## Definition

`regex` interprets the `query` field as a regular expression. `regex` is a term-level operator, meaning that the `query` field isn't analyzed.

**See also:**

- [Analyzers.](https://www.mongodb.com/docs/search/indexes/analyzers/overview.md#std-label-analyzers-ref)

- [Analyzed field example.](https://www.mongodb.com/docs/search/query/operators-collectors/regex.md#std-label-analyzed-field-example)

**Note:**

The regular expression language available to the `regex` operator is a limited subset of the PCRE (Perl Compatible Regular Expressions) library.

For detailed information, see the [Class RegExp](https://lucene.apache.org/core/8_0_0/core/org/apache/lucene/util/automaton/RegExp.html) documentation.

## Syntax

`regex` has the following syntax:

```javascript
{
  $search: {
    "index": <index name>, // optional, defaults to "default"
    "regex": {
      "query": "<search-string>",
      "path": "<field-to-search>",
      "allowAnalyzedField": <boolean>,
      "score": <options>
    }
  }
}
```

## Options

`regex` uses the following terms to construct a query:

| Field | Type | Description | Necessity | Default |
| --- | --- | --- | --- | --- |
| `query` | string or array of strings | String or strings to search for. | yes | |
| `path` | string or array of strings | Indexed field or fields to search. You can also specify a wildcard path to search. | yes | |
| `allowAnalyzedField` | boolean | Must be set to `true` if the query is run against an analyzed field. | no | `false` |
| `score` | object | [Score](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref) to assign to matching search term results. Options are: `boost`: multiply the result score by the given number.; `constant`: replace the result score with the given number.; `function`: replace the result score with the given expression. | no | |

## Behavior

`regex` is a term-level operator, meaning that the `query` field is not analyzed. Regular expression searches work well with the [keyword analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/keyword.md#std-label-ref-keyword-analyzer), because it indexes fields one word at a time. To do a case-sensitive search, do not use the default analyzer, [standard analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/standard.md#std-label-ref-standard-analyzer), because the `standard` analyzer lower cases all terms. Specify a different [analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/overview.md#std-label-analyzers-ref) instead.

It is possible to use the `regex` operator to perform searches on an analyzed field by setting the `allowAnalyzedField` option to `true`, but you may get unexpected results.

**Example:**

Searching for `.*Star Trek.*` on a field indexed with the [keyword analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/keyword.md#std-label-ref-keyword-analyzer) finds all documents in which the field contains the string `Star Trek` in any context. Searching for `.*Star
    Trek.*` on a field indexed with the [standard analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/standard.md#std-label-ref-standard-analyzer) finds nothing, because there is a space between `Star` and `Trek`, and the index contains no spaces.

## Lucene Regular Expression Behavior

The MongoDB Search `regex` operator uses the [Lucene regular expression engine](https://lucene.apache.org/core/8_0_0/core/org/apache/lucene/util/automaton/RegExp.html), which differs from [Perl Compatible Regular Expressions.](https://www.pcre.org/)

### Reserved characters

The following characters are reserved as operators when used in regular expressions:

`. ? + * | { } [ ] ( ) < > " \ @ #`

To use any of the above characters literally in a matching expression, precede it with a `\` character.

**Example:**

`who\?` *matches "who?"*

When using the escape character in [`mongosh`](https://www.mongodb.com/docs/mongodb-shell.md#mongodb-binary-bin.mongosh) or with a [driver](https://www.mongodb.com/docs/drivers/), you must use a double backslash before the character to be escaped.

**Example:**

To create a wildcard expression which searches for any string containing a literal asterisk in an aggregation pipeline, use the following expression:

```none
"*\\**"
```

The first and last asterisks act as wildcards which match any characters, and the `\\*` matches a literal asterisk.

Use the following expression to escape a literal backslash:

```none
"*\\\*"
```

### Supported Operators

| Operator | Description | Example |
| --- | --- | --- |
| `.` | Matches any character. | `x.z` *matches "xyz", "xaz", etc.* |
| `?` | The preceding character is optional and matches if it occurs no more than once. | `xyz?` *matches "xy" and "xyz"* |
| `+` | The preceding character matches if it occurs one or more times. | `xy+` *matches "xy", "xyy", "xyyy", etc.* |
| `*` | The preceding character matches if it occurs any number of times. | `xyz*` *matches "xy", "xyz", "xyzz", etc.* |
| `|` | The `OR` operator. The expression matches if either of the two patterns on either side of the `|` operator matches. | `abc|xyz` *matches "abc" or "xyz"* |
| `{<number>}` | The preceding character matches if it occurs exactly <number> times. | `xyz{3}` *matches "xyzzz"* |
| `()` | Characters inside parentheses are treated as a single unit for matching purposes. | `xyz(abc)[2]` *matches "xyzabcabc"* |
| `[]` | Matches any of the characters inside the square brackets. Adding a `^` to the beginning matches any character except those within the square brackets. Inside the square brackets, `-` indicates a range, unless `-` is the first character or is escaped with a `\`. | `[xyz]` *matches "x", "y", and "z"*`[^abc]` *matches any character except "a", "b", or "c"*`[a-d]` *matches "a", "b", "c", or "d"*`[0-9]` *matches any numeric character from 0 through 9* |
| `<>` | Match a numeric range. | `<1-3>` *matches "1", "2", and "3"* |
| `#` | The empty language operator. The `#` operator does not match any string, including an empty string. | `#|xyz` *matches "xyz" and nothing else* |

### Unsupported Operators

`regex` does not support anchor operators. For example, these operators are not supported:

- `^`, which matches the beginning of a line.

- `$`, which matches the end of a line.

To match a term, the regular expression must match the entire string.

## Examples

The following examples use the `movies` collection in the `sample_mflix` database with a custom index definition that uses the [keyword analyzer](https://www.mongodb.com/docs/search/indexes/analyzers/keyword.md#std-label-ref-keyword-analyzer). If you have the [sample dataset](https://www.mongodb.com/docs/manual/sample-data.md#std-label-available-sample-datasets) on your cluster, you can create a MongoDB Search index on the `movies` collection and run the example queries on your cluster.

### Index Definition

The following index definition indexes the `title` field in the `movies` collection with the [keyword analyzer:](https://www.mongodb.com/docs/search/indexes/analyzers/keyword.md#std-label-ref-keyword-analyzer)

```javascript
{
  "mappings": {
    "fields": {
      "title": {
        "analyzer": "lucene.keyword",
        "type": "string"
      },
      "genres": {
        "type": "token"
      }
    }
  }
}
```

### Term Position

The following example uses the regular expression `.*` to find movie titles that contain the term `summer` anywhere in the `title` and returns the number of movies that match the criteria in each genre.

```javascript
db.movies.aggregate([
  {
    "$searchMeta": {
      "facet": {
        "operator": {
          "regex": {
            "path": "title",
            "query": ".*summer.*"
          }
        },
        "facets": {
          "genresFacet": {
            "type": "string",
            "path": "genres"
          }
        }
      }
    }
  }
])
```

**Output:**

```javascript
[
  {
    count: { lowerBound: Long('6') },
    facet: {
      genresFacet: {
        buckets: [
          { _id: 'Comedy', count: Long('5') },
          { _id: 'Fantasy', count: Long('3') },
          { _id: 'Romance', count: Long('3') },
          { _id: 'Drama', count: Long('2') },
          { _id: 'Horror', count: Long('1') },
          { _id: 'Mystery', count: Long('1') }
        ]
      }
    }
  }
]
```

The following example searches all `title` fields for movie titles that end with the word `Seattle`. The `(.*)` regular expression matches any number of characters.

```javascript
db.movies.aggregate([
  {
    "$search": {
        "regex": {
          "path": "title",
          "query": "(.*) Seattle"
        }
    }
  },
  {
    $project: {
        "_id": 0,
        "title": 1
    }
  }
])
```

**Output:**

```javascript
[ { title: 'Sleepless in Seattle' }, { title: 'Battle in Seattle' } ]
```

### Range of Numbers

The following example uses the regular expression `[0-9]{2} (.){4}s` to find movie titles which begin with a 2-digit number followed by a space, and end with a 5-letter word ending in `s`.

```javascript
db.movies.aggregate([
  {
    "$search": {
        "regex": {
          "path": "title",
          "query": "[0-9]{2} (.){4}s"
        }
    }
  },
  {
    $project: {
        "_id": 0,
        "title": 1
    }
  }
])
```

**Output:**

```javascript
[
  { title: '20 Dates' },
  { title: '25 Watts' },
  { title: '21 Grams' },
  { title: '13 Lakes' },
  { title: '18 Meals' },
  { title: '26 Years' },
  { title: '99 Homes' },
  { title: '45 Years' }
]
```

### Multi-Word Phrase

The following example uses the regular expression `.*Toy Story.*` to find all movie titles that contain the phrase `Toy Story`. Because the search field uses the keyword analyzer, the regex matches the phrase exactly as stored, including the space between words.

```javascript
db.movies.aggregate([
  {
    "$search": {
        "regex": {
          "path": "title",
          "query": ".*Toy Story.*"
        }
    }
  },
  {
    $project: {
        "_id": 0,
        "title": 1
    }
  }
])
```

**Output:**

```javascript
[
  { title: 'Toy Story' },
  { title: 'Toy Story 2' },
  { title: 'Toy Story 3' },
  { title: 'Toy Story of Terror' },
  { title: 'Toy Story That Time Forgot' }
]
```

### Array of Strings

The following example uses an array of regular expressions to find movie titles that match any of the specified patterns. The query finds titles that end with `Seattle` or contain `Toy Story`.

```javascript
db.movies.aggregate([
  {
    "$search": {
        "regex": {
          "path": "title",
          "query": ["(.*) Seattle", ".*Toy Story.*"]
        }
    }
  },
  {
    $project: {
        "_id": 0,
        "title": 1
    }
  }
])
```

**Output:**

```javascript
[
  { title: 'Sleepless in Seattle' },
  { title: 'Toy Story' },
  { title: 'Toy Story 2' },
  { title: 'Toy Story 3' },
  { title: 'Battle in Seattle' },
  { title: 'Toy Story of Terror' },
  { title: 'Toy Story That Time Forgot' }
]
```

### Case-Sensitive Search

The following example demonstrates case-sensitive matching. Because the index uses the `lucene.keyword` analyzer, which preserves the original capitalization of each indexed value, the query must match the exact case of stored titles. The query `.*Sleepless.*` matches `Sleepless in Seattle`, but `.*sleepless.*` returns no results.

```javascript
db.movies.aggregate([
  {
    "$search": {
        "regex": {
          "path": "title",
          "query": ".*sleepless.*"
        }
    }
  },
  {
    $project: {
        "_id": 0,
        "title": 1
    }
  }
])
```

**Output:**

```javascript
<no results>
```
