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

# MongoDB Search Query Performance

Improve your MongoDB Search query performance by understanding how query complexity, operators, and aggregation pipeline stages affect cluster performance. Use the recommendations below to structure queries efficiently for your deployment type.

## Consider Query Operators and Query Complexity

The complexity level of MongoDB Search queries and the type of [operators](https://www.mongodb.com/docs/search/query/operators-collectors/overview.md#std-label-fts-operators) used can affect database performance for the node that `mongot` runs on.

Highly complex queries, such as queries with multiple clauses that use the [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator, or queries which use the [regex](https://www.mongodb.com/docs/search/query/operators-collectors/regex.md#std-label-regex-ref) (regular expression) or the [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) operator, are resource-intensive.

### Compound Queries

If your query includes multiple nested [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) statements, ensure that these are not redundant. If the clauses are added programmatically, consider implementing the logic in the application to avoid inclusion of redundant clauses in the queries. Every score calculation per field that `mongot` performs, such as for the `must` and `should` clauses, increases execution time.  To optimize performance, place non-scoring operators such as [equals](https://www.mongodb.com/docs/search/query/operators-collectors/equals.md#std-label-equals-ref), [range](https://www.mongodb.com/docs/search/query/operators-collectors/range.md#std-label-range-ref), and [in](https://www.mongodb.com/docs/search/query/operators-collectors/in.md#std-label-in-ref) in the [`filter`](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#mongodb-data-filter) clause to avoid unnecessary scoring operations.

### Faceted Search

You can use the MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector to extract metadata and avoid running multiple queries for search results and metadata. You can use `$search.facet` to retrieve both documents and metadata in a single query. If you only need metadata, use `$searchMeta.facet` to avoid document lookup. For an example, see the [Metadata and Search Results example.](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

## Use `$limit` Before `$facet`

Using a [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) aggregation pipeline stage after a [`$facet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet) aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) before [`$facet`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet)

**Example:**

```json
{
  {
    "$search": {...}
  },
  { "$limit": 20 },
  {
    "$facet": {
      "results": [],
      "totalCount": $$SEARCH_META
    }
  }
}
```

For a demonstration, see the following examples:

- [Metadata and Search Results Example](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

- [Facet Example](https://www.mongodb.com/docs/search/query/counting.md#std-label-fts-count-aggregation-variable)

## Minimize Additional MQL Aggregation Stages

Try to encapsulate the entire search logic within the `$search` stage itself and minimize using additional blocking stages, such as [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count), [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match), or [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort). This optimizes the MongoDB Search index usage, and reduces the need for additional database operations in `mongod`.

### Use `compound.filter` Instead of `$match`

For queries that require multiple filtering operations, use the [`compound` Operator](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator with `filter` clauses. If you must use the [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage in your aggregation pipeline, consider using the [storedSource](https://www.mongodb.com/docs/search/indexes/stored-source-definition.md#std-label-fts-stored-source-definition) option to store only the fields that your [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) condition needs. You can then use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) option to retrieve stored fields and avoid the `mongod` full document lookup.

**See also:**

- [Storing Source Fields](https://www.mongodb.com/docs/search/performance/index-performance.md#std-label-perf-ref-stored-source)

- [$match Example](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-egs)

### Use `facet` Instead of `$group`

If you use [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) to get basic counts for field aggregations, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. If you need only metadata results, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside inside the [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `count` Instead of `$count`

If you use [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count) to get a count of the number of documents, we recommend that you use [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) or [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `sort`, `near`, or `returnStoredSource` Instead of  `$sort`

- For sorting numeric, date, string, boolean, UUID, and objectID fields, use the `sort` option with the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. To learn more, see [Sort MongoDB Search Results.](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref)

- For sorting geo fields, use the [near](https://www.mongodb.com/docs/search/query/operators-collectors/near.md#std-label-near-ref) operator.

- To sort other fields, use `$sort` and [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) fields.

## Avoid Use of `$skip` After `$search`

Using [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` or `searchBefore` options to paginate results. To learn more, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:

- [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` the last result on Page 2

- [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) documents on Pages 3 and 4

- [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) results for Page 5

Here, your query is optimized to skip only 2 pages of results, instead of skipping 4 pages if you didn't use `searchAfter`. For a demonstration of this, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

## Use `$search` Instead of `$text` or `$regex`

For applications that rely heavily on MongoDB [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) and [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search). The `$search` aggregation pipeline stage provides features that are either not available through the MongoDB operators or are available through the MongoDB operators but not as performant as MongoDB Search `$search`.

The following table shows how MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex), [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text), and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) address your application's requirements.

| If your application requires... | Use... | Because... |
| --- | --- | --- |
| Datastore to respect write concerns | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) | For transactions with heavy reads after writes, we recommend [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex). For [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search), reads after writes should be rare. |
| Cluster optimized for write performance | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search indexes don't degrade cluster write performance. |
| Searching through large data sets | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. |
| Language awareness | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports many [language analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/language.md#std-label-ref-language-analyzers) that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. |
| Case-insensitive text search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) offers more capabilities than [`$regex`.](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) |
| Highlighting result text | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [highlighting](https://www.mongodb.com/docs/search/query/highlighting.md#std-label-highlight-ref) allows you to contextualize the documents in the results, which is essential for natural language queries. |
| Geospatial-aware search queries | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) or [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) treat geospatial parameters differently. In MongoDB, lines between coordinates are spherical, which is well-suited for coordinates for long distance such as air flight. MongoDB Search uses Lucene, which draws a straight line between coordinates and is well-suited for short distance. |
| Autocompletion of search queries | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of characters (nGrams), MongoDB Search includes `edgeGrams` for left-to-right autocomplete, `nGrams` for autocomplete of languages that don't have whitespace, and `rightEdgeGram` for autocomplete of languages that you write and read right-to-left. For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of words (wordGrams), MongoDB Search includes [shingle](https://www.mongodb.com/docs/search/indexes/analyzers/token-filters.md#std-label-shingle-tf-ref) token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. |
| Fuzzy matching on text input | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support `fuzzy` matching to filter on input text and address misspelled words (typos). |
| Filtering based on multiple strings | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) supports filtering based on multiple strings. |
| Relevance score sorted search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses the [BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25) for determining the search relevance score of documents. It supports advanced configuration through [`boost`](https://www.mongodb.com/docs/search/query/score/modify-score.md#std-label-scoring-boost) expressions like multiply and gaussian decay, as well as analyzers, search operators, and synonyms. To learn more, see [Modify the Score of the Documents in the Results.](https://www.mongodb.com/docs/search/query/score/customize-score.md#std-label-compound-query-custom-score-tutorial) |
| Partial indexes | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports partial indexing by using a View with a `$match` expression. To learn more, see [Example: Filter Documents.](https://www.mongodb.com/docs/search/about/view-support.md#std-label-partially-indexed-collection) |
| Patial match | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support partial match queries. |
| Single compound index on arrays | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search term indexes are intersected in a single MongoDB Search index and eliminate the need for compound indexes for filtering on arrays. |
| Synonyms search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [synonyms](https://www.mongodb.com/docs/search/indexes/synonyms.md#std-label-synonyms-ref) defined in a separate collection, which you can reference in your search index for use. To learn more, see the [How to Use Synonyms with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/synonyms-tutorial.md#std-label-synonyms-tutorial) tutorial. |
| Faceting for counts | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides fast [counts](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) of documents based on text criteria, and also supports [faceted](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) search for numbers and dates. To learn more, see [How to Use Facets with MongoDB Search.](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) |
| Extract metadata | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector returns metadata and doesn't require you to run multiple queries for retrieving metadata. To learn more, see the [How to Use Facets with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) tutorial. |
| Custom analyzers | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [custom analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/custom.md#std-label-custom-analyzers) to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP (HyperText Transport Protocol) or HTTPS (Secure HyperText Transport Protocol) URL (Uniform Resource Locator)s using custom analyzers. |
| Searching phrases or multiple words | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [phrase](https://www.mongodb.com/docs/search/query/operators-collectors/phrase.md#std-label-phrase-ref) operator supports searching for a sequence of terms. |
| Searching with regular expression | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides improved performance when you use the MongoDB Search [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operator instead. |

**See also:**

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-text-to-search) - describes how you can replace [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) aggregation pipeline stage in your query with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve both the flexibility and performance of these queries.

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-regex-to-search) - describes how you can replace inefficient regex matching with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve the performance of text queries.

### Learn More

- [MongoDB Text Search: B-Tree vs Inverted Index, Use Search Instead (Part 1)](https://medium.com/mongodb/mongodb-text-search-b-tree-vs-inverted-index-use-search-instead-part-1-501560cb0d59)

- [MongoDB Text Search: Finding Words — Use Search Instead (Part 2)](https://medium.com/mongodb/mongodb-text-search-finding-words-use-search-instead-part-2-76219c7303b5)

- [MongoDB Text Search: Substring Pattern Matching Including Regex and Wildcard, Use Search Instead (Part 3)](https://medium.com/mongodb/mongodb-text-search-substring-pattern-matching-including-regex-and-wildcard-use-search-instead-3633c6f7e604)

## Monitor Performance

You can [monitor](https://www.mongodb.com/docs/atlas/monitor-cluster-metrics.md#std-label-monitor-cluster-metrics) your Atlas cluster and view charts with performance statistics on the Atlas Metrics tab. These metrics can help you see how MongoDB Search queries and index building affect your cluster's performance. To learn more, see [Review MongoDB Search Metrics.](https://www.mongodb.com/docs/atlas/review-atlas-search-metrics.md#std-label-review-atlas-search-metrics)

Atlas might trigger some Atlas [alerts](https://www.mongodb.com/docs/atlas/alerts/) when:

- MongoDB Search queries your clusters, which can impact Atlas performance metrics, such as the [query targeting](https://www.mongodb.com/docs/atlas/reference/alert-resolutions/query-targeting.md#std-label-query-targeting-resolution) metrics.

The [change streams](https://www.mongodb.com/docs/manual/changeStreams.md#std-label-changeStreams) cursors that the MongoDB Search process (`mongot`) uses to keep MongoDB Search indexes updated can contribute to the query targeting ratio and trigger [query targeting alerts](https://www.mongodb.com/docs/atlas/reference/alert-conditions.md#std-label-query-targeting-alerts) if the ratio is high.

- MongoDB Search replicates data from MongoDB, which contributes to the [metrics](https://www.mongodb.com/docs/atlas/monitor-cluster-metrics.md#std-label-monitor-cluster-metrics) measured in Atlas, such as the number of getmore operations.

**Note:**

If your cluster's resources are stretched or near the limits of acceptable performance, consider [upgrading](https://www.mongodb.com/docs/atlas/scale-cluster.md#std-label-scale-cluster) to a larger cluster tier before implementing MongoDB Search functionality.

**See also:**

- [Storing Source Fields](https://www.mongodb.com/docs/search/performance/index-performance.md#std-label-perf-ref-stored-source)

- [$sort Example](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-egs)

## Continue Learning

Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using [explain](https://www.mongodb.com/docs/search/query/explain.md#std-label-explain-ref) and [$search score details.](https://www.mongodb.com/docs/search/query/score/get-details.md#std-label-fts-score-details)

*Duration: 5 Minutes*

## Consider Query Operators and Query Complexity

The complexity level of MongoDB Search queries and the type of [operators](https://www.mongodb.com/docs/search/query/operators-collectors/overview.md#std-label-fts-operators) used can affect database performance for the node that `mongot` runs on.

Highly complex queries, such as queries with multiple clauses that use the [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator, or queries which use the [regex](https://www.mongodb.com/docs/search/query/operators-collectors/regex.md#std-label-regex-ref) (regular expression) or the [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) operator, are resource-intensive.

### Compound Queries

If your query includes multiple nested [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) statements, ensure that these are not redundant. If the clauses are added programmatically, consider implementing the logic in the application to avoid inclusion of redundant clauses in the queries. Every score calculation per field that `mongot` performs, such as for the `must` and `should` clauses, increases execution time.  To optimize performance, place non-scoring operators such as [equals](https://www.mongodb.com/docs/search/query/operators-collectors/equals.md#std-label-equals-ref), [range](https://www.mongodb.com/docs/search/query/operators-collectors/range.md#std-label-range-ref), and [in](https://www.mongodb.com/docs/search/query/operators-collectors/in.md#std-label-in-ref) in the [`filter`](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#mongodb-data-filter) clause to avoid unnecessary scoring operations.

### Faceted Search

You can use the MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector to extract metadata and avoid running multiple queries for search results and metadata. You can use `$search.facet` to retrieve both documents and metadata in a single query. If you only need metadata, use `$searchMeta.facet` to avoid document lookup. For an example, see the [Metadata and Search Results example.](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

## Use `$limit` Before `$facet`

Using a [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) aggregation pipeline stage after a [`$facet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet) aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) before [`$facet`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet)

**Example:**

```json
{
  {
    "$search": {...}
  },
  { "$limit": 20 },
  {
    "$facet": {
      "results": [],
      "totalCount": $$SEARCH_META
    }
  }
}
```

For a demonstration, see the following examples:

- [Metadata and Search Results Example](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

- [Facet Example](https://www.mongodb.com/docs/search/query/counting.md#std-label-fts-count-aggregation-variable)

## Minimize Additional MQL Aggregation Stages

Try to encapsulate the entire search logic within the `$search` stage itself and minimize using additional blocking stages, such as [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count), [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match), or [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort). This optimizes the MongoDB Search index usage, and reduces the need for additional database operations in `mongod`.

### Use `compound.filter` Instead of `$match`

For queries that require multiple filtering operations, use the [`compound` Operator](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator with `filter` clauses. If you must use the [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage in your aggregation pipeline, consider using the [storedSource](https://www.mongodb.com/docs/search/indexes/stored-source-definition.md#std-label-fts-stored-source-definition) option to store only the fields that your [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) condition needs. You can then use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) option to retrieve stored fields and avoid the `mongod` full document lookup.

**See also:**

- [Storing Source Fields](https://www.mongodb.com/docs/search/performance/index-performance.md#std-label-perf-ref-stored-source)

- [$match Example](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-egs)

### Use `facet` Instead of `$group`

If you use [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) to get basic counts for field aggregations, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. If you need only metadata results, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside inside the [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `count` Instead of `$count`

If you use [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count) to get a count of the number of documents, we recommend that you use [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) or [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `sort`, `near`, or `returnStoredSource` Instead of  `$sort`

- For sorting numeric, date, string, boolean, UUID, and objectID fields, use the `sort` option with the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. To learn more, see [Sort MongoDB Search Results.](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref)

- For sorting geo fields, use the [near](https://www.mongodb.com/docs/search/query/operators-collectors/near.md#std-label-near-ref) operator.

- To sort other fields, use `$sort` and [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) fields.

## Avoid Use of `$skip` After `$search`

Using [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` or `searchBefore` options to paginate results. To learn more, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:

- [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` the last result on Page 2

- [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) documents on Pages 3 and 4

- [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) results for Page 5

Here, your query is optimized to skip only 2 pages of results, instead of skipping 4 pages if you didn't use `searchAfter`. For a demonstration of this, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

## Use `$search` Instead of `$text` or `$regex`

For applications that rely heavily on MongoDB [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) and [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search). The `$search` aggregation pipeline stage provides features that are either not available through the MongoDB operators or are available through the MongoDB operators but not as performant as MongoDB Search `$search`.

The following table shows how MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex), [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text), and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) address your application's requirements.

| If your application requires... | Use... | Because... |
| --- | --- | --- |
| Datastore to respect write concerns | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) | For transactions with heavy reads after writes, we recommend [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex). For [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search), reads after writes should be rare. |
| Cluster optimized for write performance | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search indexes don't degrade cluster write performance. |
| Searching through large data sets | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. |
| Language awareness | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports many [language analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/language.md#std-label-ref-language-analyzers) that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. |
| Case-insensitive text search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) offers more capabilities than [`$regex`.](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) |
| Highlighting result text | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [highlighting](https://www.mongodb.com/docs/search/query/highlighting.md#std-label-highlight-ref) allows you to contextualize the documents in the results, which is essential for natural language queries. |
| Geospatial-aware search queries | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) or [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) treat geospatial parameters differently. In MongoDB, lines between coordinates are spherical, which is well-suited for coordinates for long distance such as air flight. MongoDB Search uses Lucene, which draws a straight line between coordinates and is well-suited for short distance. |
| Autocompletion of search queries | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of characters (nGrams), MongoDB Search includes `edgeGrams` for left-to-right autocomplete, `nGrams` for autocomplete of languages that don't have whitespace, and `rightEdgeGram` for autocomplete of languages that you write and read right-to-left. For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of words (wordGrams), MongoDB Search includes [shingle](https://www.mongodb.com/docs/search/indexes/analyzers/token-filters.md#std-label-shingle-tf-ref) token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. |
| Fuzzy matching on text input | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support `fuzzy` matching to filter on input text and address misspelled words (typos). |
| Filtering based on multiple strings | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) supports filtering based on multiple strings. |
| Relevance score sorted search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses the [BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25) for determining the search relevance score of documents. It supports advanced configuration through [`boost`](https://www.mongodb.com/docs/search/query/score/modify-score.md#std-label-scoring-boost) expressions like multiply and gaussian decay, as well as analyzers, search operators, and synonyms. To learn more, see [Modify the Score of the Documents in the Results.](https://www.mongodb.com/docs/search/query/score/customize-score.md#std-label-compound-query-custom-score-tutorial) |
| Partial indexes | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports partial indexing by using a View with a `$match` expression. To learn more, see [Example: Filter Documents.](https://www.mongodb.com/docs/search/about/view-support.md#std-label-partially-indexed-collection) |
| Patial match | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support partial match queries. |
| Single compound index on arrays | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search term indexes are intersected in a single MongoDB Search index and eliminate the need for compound indexes for filtering on arrays. |
| Synonyms search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [synonyms](https://www.mongodb.com/docs/search/indexes/synonyms.md#std-label-synonyms-ref) defined in a separate collection, which you can reference in your search index for use. To learn more, see the [How to Use Synonyms with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/synonyms-tutorial.md#std-label-synonyms-tutorial) tutorial. |
| Faceting for counts | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides fast [counts](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) of documents based on text criteria, and also supports [faceted](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) search for numbers and dates. To learn more, see [How to Use Facets with MongoDB Search.](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) |
| Extract metadata | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector returns metadata and doesn't require you to run multiple queries for retrieving metadata. To learn more, see the [How to Use Facets with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) tutorial. |
| Custom analyzers | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [custom analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/custom.md#std-label-custom-analyzers) to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP (HyperText Transport Protocol) or HTTPS (Secure HyperText Transport Protocol) URL (Uniform Resource Locator)s using custom analyzers. |
| Searching phrases or multiple words | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [phrase](https://www.mongodb.com/docs/search/query/operators-collectors/phrase.md#std-label-phrase-ref) operator supports searching for a sequence of terms. |
| Searching with regular expression | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides improved performance when you use the MongoDB Search [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operator instead. |

**See also:**

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-text-to-search) - describes how you can replace [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) aggregation pipeline stage in your query with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve both the flexibility and performance of these queries.

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-regex-to-search) - describes how you can replace inefficient regex matching with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve the performance of text queries.

### Learn More

- [MongoDB Text Search: B-Tree vs Inverted Index, Use Search Instead (Part 1)](https://medium.com/mongodb/mongodb-text-search-b-tree-vs-inverted-index-use-search-instead-part-1-501560cb0d59)

- [MongoDB Text Search: Finding Words — Use Search Instead (Part 2)](https://medium.com/mongodb/mongodb-text-search-finding-words-use-search-instead-part-2-76219c7303b5)

- [MongoDB Text Search: Substring Pattern Matching Including Regex and Wildcard, Use Search Instead (Part 3)](https://medium.com/mongodb/mongodb-text-search-substring-pattern-matching-including-regex-and-wildcard-use-search-instead-3633c6f7e604)

## Continue Learning

Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using [explain](https://www.mongodb.com/docs/search/query/explain.md#std-label-explain-ref) and [$search score details.](https://www.mongodb.com/docs/search/query/score/get-details.md#std-label-fts-score-details)

*Duration: 5 Minutes*

## Consider Query Operators and Query Complexity

The complexity level of MongoDB Search queries and the type of [operators](https://www.mongodb.com/docs/search/query/operators-collectors/overview.md#std-label-fts-operators) used can affect database performance for the node that `mongot` runs on.

Highly complex queries, such as queries with multiple clauses that use the [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator, or queries which use the [regex](https://www.mongodb.com/docs/search/query/operators-collectors/regex.md#std-label-regex-ref) (regular expression) or the [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) operator, are resource-intensive.

### Compound Queries

If your query includes multiple nested [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) statements, ensure that these are not redundant. If the clauses are added programmatically, consider implementing the logic in the application to avoid inclusion of redundant clauses in the queries. Every score calculation per field that `mongot` performs, such as for the `must` and `should` clauses, increases execution time.  To optimize performance, place non-scoring operators such as [equals](https://www.mongodb.com/docs/search/query/operators-collectors/equals.md#std-label-equals-ref), [range](https://www.mongodb.com/docs/search/query/operators-collectors/range.md#std-label-range-ref), and [in](https://www.mongodb.com/docs/search/query/operators-collectors/in.md#std-label-in-ref) in the [`filter`](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#mongodb-data-filter) clause to avoid unnecessary scoring operations.

### Faceted Search

You can use the MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector to extract metadata and avoid running multiple queries for search results and metadata. You can use `$search.facet` to retrieve both documents and metadata in a single query. If you only need metadata, use `$searchMeta.facet` to avoid document lookup. For an example, see the [Metadata and Search Results example.](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

## Use `$limit` Before `$facet`

Using a [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) aggregation pipeline stage after a [`$facet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet) aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) before [`$facet`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet.md#mongodb-pipeline-pipe.-facet)

**Example:**

```json
{
  {
    "$search": {...}
  },
  { "$limit": 20 },
  {
    "$facet": {
      "results": [],
      "totalCount": $$SEARCH_META
    }
  }
}
```

For a demonstration, see the following examples:

- [Metadata and Search Results Example](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-egs)

- [Facet Example](https://www.mongodb.com/docs/search/query/counting.md#std-label-fts-count-aggregation-variable)

## Minimize Additional MQL Aggregation Stages

Try to encapsulate the entire search logic within the `$search` stage itself and minimize using additional blocking stages, such as [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group), [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count), [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match), or [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort). This optimizes the MongoDB Search index usage, and reduces the need for additional database operations in `mongod`.

### Use `compound.filter` Instead of `$match`

For queries that require multiple filtering operations, use the [`compound` Operator](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) operator with `filter` clauses. If you must use the [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) stage in your aggregation pipeline, consider using the [storedSource](https://www.mongodb.com/docs/search/indexes/stored-source-definition.md#std-label-fts-stored-source-definition) option to store only the fields that your [`$match`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match.md#mongodb-pipeline-pipe.-match) condition needs. You can then use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) option to retrieve stored fields and avoid the `mongod` full document lookup.

**See also:**

- [Storing Source Fields](https://www.mongodb.com/docs/search/performance/index-performance.md#std-label-perf-ref-stored-source)

- [$match Example](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-egs)

### Use `facet` Instead of `$group`

If you use [`$group`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/group.md#mongodb-pipeline-pipe.-group) to get basic counts for field aggregations, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. If you need only metadata results, you can use [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) inside inside the [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `count` Instead of `$count`

If you use [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count.md#mongodb-pipeline-pipe.-count) to get a count of the number of documents, we recommend that you use [count](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) inside the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) or [`$searchMeta`](https://www.mongodb.com/docs/search/query/aggregation-stages/searchmeta.md#mongodb-pipeline-pipe.-searchMeta) stage instead.

### Use `sort`, `near`, or `returnStoredSource` Instead of  `$sort`

- For sorting numeric, date, string, boolean, UUID, and objectID fields, use the `sort` option with the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) stage. To learn more, see [Sort MongoDB Search Results.](https://www.mongodb.com/docs/search/query/sort.md#std-label-sort-ref)

- For sorting geo fields, use the [near](https://www.mongodb.com/docs/search/query/operators-collectors/near.md#std-label-near-ref) operator.

- To sort other fields, use `$sort` and [returnStoredSource](https://www.mongodb.com/docs/search/query/return-stored-source.md#std-label-fts-return-stored-source-option) fields.

## Avoid Use of `$skip` After `$search`

Using [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) and [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` or `searchBefore` options to paginate results. To learn more, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:

- [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) `searchAfter` the last result on Page 2

- [`$skip`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip.md#mongodb-pipeline-pipe.-skip) documents on Pages 3 and 4

- [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) results for Page 5

Here, your query is optimized to skip only 2 pages of results, instead of skipping 4 pages if you didn't use `searchAfter`. For a demonstration of this, see [Paginate the Results.](https://www.mongodb.com/docs/search/query/paginate-results.md#std-label-fts-paginate-results)

## Use `$search` Instead of `$text` or `$regex`

For applications that rely heavily on MongoDB [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) and [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search). The `$search` aggregation pipeline stage provides features that are either not available through the MongoDB operators or are available through the MongoDB operators but not as performant as MongoDB Search `$search`.

The following table shows how MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex), [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text), and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) address your application's requirements.

| If your application requires... | Use... | Because... |
| --- | --- | --- |
| Datastore to respect write concerns | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) | For transactions with heavy reads after writes, we recommend [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex). For [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search), reads after writes should be rare. |
| Cluster optimized for write performance | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search indexes don't degrade cluster write performance. |
| Searching through large data sets | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. |
| Language awareness | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports many [language analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/language.md#std-label-ref-language-analyzers) that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. |
| Case-insensitive text search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) offers more capabilities than [`$regex`.](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) |
| Highlighting result text | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [highlighting](https://www.mongodb.com/docs/search/query/highlighting.md#std-label-highlight-ref) allows you to contextualize the documents in the results, which is essential for natural language queries. |
| Geospatial-aware search queries | [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) or [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB [`$regex`](https://www.mongodb.com/docs/manual/reference/operator/query/regex.md#mongodb-query-op.-regex) and MongoDB Search [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) treat geospatial parameters differently. In MongoDB, lines between coordinates are spherical, which is well-suited for coordinates for long distance such as air flight. MongoDB Search uses Lucene, which draws a straight line between coordinates and is well-suited for short distance. |
| Autocompletion of search queries | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of characters (nGrams), MongoDB Search includes `edgeGrams` for left-to-right autocomplete, `nGrams` for autocomplete of languages that don't have whitespace, and `rightEdgeGram` for autocomplete of languages that you write and read right-to-left. For [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) of words (wordGrams), MongoDB Search includes [shingle](https://www.mongodb.com/docs/search/indexes/analyzers/token-filters.md#std-label-shingle-tf-ref) token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. |
| Fuzzy matching on text input | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [text](https://www.mongodb.com/docs/search/query/operators-collectors/text.md#std-label-text-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support `fuzzy` matching to filter on input text and address misspelled words (typos). |
| Filtering based on multiple strings | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [compound](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref) supports filtering based on multiple strings. |
| Relevance score sorted search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search uses the [BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25) for determining the search relevance score of documents. It supports advanced configuration through [`boost`](https://www.mongodb.com/docs/search/query/score/modify-score.md#std-label-scoring-boost) expressions like multiply and gaussian decay, as well as analyzers, search operators, and synonyms. To learn more, see [Modify the Score of the Documents in the Results.](https://www.mongodb.com/docs/search/query/score/customize-score.md#std-label-compound-query-custom-score-tutorial) |
| Partial indexes | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports partial indexing by using a View with a `$match` expression. To learn more, see [Example: Filter Documents.](https://www.mongodb.com/docs/search/about/view-support.md#std-label-partially-indexed-collection) |
| Patial match | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [wildcard](https://www.mongodb.com/docs/search/query/operators-collectors/wildcard.md#std-label-wildcard-ref) and [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operators support partial match queries. |
| Single compound index on arrays | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search term indexes are intersected in a single MongoDB Search index and eliminate the need for compound indexes for filtering on arrays. |
| Synonyms search | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [synonyms](https://www.mongodb.com/docs/search/indexes/synonyms.md#std-label-synonyms-ref) defined in a separate collection, which you can reference in your search index for use. To learn more, see the [How to Use Synonyms with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/synonyms-tutorial.md#std-label-synonyms-tutorial) tutorial. |
| Faceting for counts | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides fast [counts](https://www.mongodb.com/docs/search/query/counting.md#std-label-count-ref) of documents based on text criteria, and also supports [faceted](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) search for numbers and dates. To learn more, see [How to Use Facets with MongoDB Search.](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) |
| Extract metadata | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [`facet` (MongoDB Search Operator)](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-ref) collector returns metadata and doesn't require you to run multiple queries for retrieving metadata. To learn more, see the [How to Use Facets with MongoDB Search](https://www.mongodb.com/docs/search/tutorial/facet-tutorial.md#std-label-facet-tutorial) tutorial. |
| Custom analyzers | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search supports [custom analyzers](https://www.mongodb.com/docs/search/indexes/analyzers/custom.md#std-label-custom-analyzers) to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP (HyperText Transport Protocol) or HTTPS (Secure HyperText Transport Protocol) URL (Uniform Resource Locator)s using custom analyzers. |
| Searching phrases or multiple words | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search [phrase](https://www.mongodb.com/docs/search/query/operators-collectors/phrase.md#std-label-phrase-ref) operator supports searching for a sequence of terms. |
| Searching with regular expression | [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) | MongoDB Search provides improved performance when you use the MongoDB Search [autocomplete](https://www.mongodb.com/docs/search/query/operators-collectors/autocomplete.md#std-label-autocomplete-ref) operator instead. |

**See also:**

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-text-to-search) - describes how you can replace [`$text`](https://www.mongodb.com/docs/manual/reference/operator/query/text.md#mongodb-query-op.-text) aggregation pipeline stage in your query with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve both the flexibility and performance of these queries.

- [Use `$search` Instead of `$text` or `$regex`](https://www.mongodb.com/docs/search/performance/query-performance.md#std-label-regex-to-search) - describes how you can replace inefficient regex matching with [`$search`](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search) to improve the performance of text queries.

### Learn More

- [MongoDB Text Search: B-Tree vs Inverted Index, Use Search Instead (Part 1)](https://medium.com/mongodb/mongodb-text-search-b-tree-vs-inverted-index-use-search-instead-part-1-501560cb0d59)

- [MongoDB Text Search: Finding Words — Use Search Instead (Part 2)](https://medium.com/mongodb/mongodb-text-search-finding-words-use-search-instead-part-2-76219c7303b5)

- [MongoDB Text Search: Substring Pattern Matching Including Regex and Wildcard, Use Search Instead (Part 3)](https://medium.com/mongodb/mongodb-text-search-substring-pattern-matching-including-regex-and-wildcard-use-search-instead-3633c6f7e604)

## Continue Learning

Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using [explain](https://www.mongodb.com/docs/search/query/explain.md#std-label-explain-ref) and [$search score details.](https://www.mongodb.com/docs/search/query/score/get-details.md#std-label-fts-score-details)

*Duration: 5 Minutes*
