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 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 operator, or queries which use the regex (regular expression) or the wildcard operator, are resource-intensive.
Compound Queries
If your query includes multiple nested compound 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, range, and in in the filter clause to avoid unnecessary scoring operations.
Faceted Search
You can use the MongoDB Search facet (MongoDB Search Operator) 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.
Use $limit Before $facet
Using a $limit aggregation pipeline stage after a $facet aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use $limit before $facet.
Example
{ { "$search": {...} }, { "$limit": 20 }, { "$facet": { "results": [], "totalCount": $$SEARCH_META } } }
For a demonstration, see the following examples:
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, $count, $match, or $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 operator with filter clauses. If you must use the $match stage in your aggregation pipeline, consider using the storedSource option to store only the fields that your $match condition needs. You can then use the $search returnStoredSource option to retrieve stored fields and avoid the mongod full document lookup.
Use facet Instead of $group
If you use $group to get basic counts for field aggregations, you can use facet (MongoDB Search Operator) inside the $search stage. If you need only metadata results, you can use facet (MongoDB Search Operator) inside inside the $searchMeta stage instead.
Use count Instead of $count
If you use $count to get a count of the number of documents, we recommend that you use count inside the $search or $searchMeta stage instead.
Use sort, near, or returnStoredSource Instead of $sort
For sorting numeric, date, string, boolean, UUID, and objectID fields, use the
sortoption with the$searchstage. To learn more, see Sort MongoDB Search Results.For sorting geo fields, use the near operator.
To sort other fields, use
$sortand returnStoredSource fields.
Avoid Use of $skip After $search
Using $skip and $limit to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the $search searchAfter or searchBefore options to paginate results. To learn more, see Paginate the Results.
To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:
$searchsearchAfterthe last result on Page 2$skipdocuments on Pages 3 and 4$limitresults 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.
Use $search Instead of $text or $regex
For applications that rely heavily on MongoDB $text and $regex queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search $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, $text, and MongoDB Search $search address your application's requirements.
If your application requires... | Use... | Because... |
|---|---|---|
Datastore to respect write concerns | ||
Cluster optimized for write performance | MongoDB Search indexes don't degrade cluster write performance. | |
Searching through large data sets | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. | |
Language awareness | MongoDB Search supports many language analyzers that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. | |
Case-insensitive text search | ||
Highlighting result text | MongoDB Search highlighting allows you to contextualize the documents in the results, which is essential for natural language queries. | |
Geospatial-aware search queries | MongoDB | |
Autocompletion of search queries | For autocomplete of characters (nGrams), MongoDB Search includes For autocomplete of words (wordGrams), MongoDB Search includes shingle token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. | |
Fuzzy matching on text input | MongoDB Search text and autocomplete operators support | |
Filtering based on multiple strings | MongoDB Search compound supports filtering based on multiple strings. | |
Relevance score sorted search | MongoDB Search uses the BM25 algorithm for determining the search relevance score of documents. It supports advanced configuration through | |
Partial indexes | MongoDB Search supports partial indexing by using a View with a | |
Patial match | MongoDB Search wildcard and autocomplete operators support partial match queries. | |
Single compound index on arrays | 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 | MongoDB Search supports synonyms 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 tutorial. | |
Faceting for counts | MongoDB Search provides fast counts of documents based on text criteria, and also supports faceted search for numbers and dates. To learn more, see How to Use Facets with MongoDB Search. | |
Extract metadata | MongoDB Search | |
Custom analyzers | MongoDB Search supports custom analyzers to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP or HTTPS URLs using custom analyzers. | |
Searching phrases or multiple words | MongoDB Search phrase operator supports searching for a sequence of terms. | |
Searching with regular expression | MongoDB Search provides improved performance when you use the MongoDB Search autocomplete operator instead. |
Tip
Use
$searchInstead of$textor$regex- describes how you can replace$textaggregation pipeline stage in your query with$searchto improve both the flexibility and performance of these queries.Use
$searchInstead of$textor$regex- describes how you can replace inefficient regex matching with$searchto improve the performance of text queries.
Learn More
Monitor Performance
You can monitor 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.
Atlas might trigger some Atlas alerts when:
- MongoDB Search queries your clusters, which can impact Atlas performance metrics, such as the query targeting metrics.
The change streams 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 if the ratio is high.
- MongoDB Search replicates data from MongoDB, which contributes to the 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 to a larger cluster tier before implementing MongoDB Search functionality.
Continue Learning
Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using explain and $search score details.
Duration: 5 Minutes
Consider Query Operators and Query Complexity
The complexity level of MongoDB Search queries and the type of 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 operator, or queries which use the regex (regular expression) or the wildcard operator, are resource-intensive.
Compound Queries
If your query includes multiple nested compound 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, range, and in in the filter clause to avoid unnecessary scoring operations.
Faceted Search
You can use the MongoDB Search facet (MongoDB Search Operator) 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.
Use $limit Before $facet
Using a $limit aggregation pipeline stage after a $facet aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use $limit before $facet.
Example
{ { "$search": {...} }, { "$limit": 20 }, { "$facet": { "results": [], "totalCount": $$SEARCH_META } } }
For a demonstration, see the following examples:
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, $count, $match, or $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 operator with filter clauses. If you must use the $match stage in your aggregation pipeline, consider using the storedSource option to store only the fields that your $match condition needs. You can then use the $search returnStoredSource option to retrieve stored fields and avoid the mongod full document lookup.
Use facet Instead of $group
If you use $group to get basic counts for field aggregations, you can use facet (MongoDB Search Operator) inside the $search stage. If you need only metadata results, you can use facet (MongoDB Search Operator) inside inside the $searchMeta stage instead.
Use count Instead of $count
If you use $count to get a count of the number of documents, we recommend that you use count inside the $search or $searchMeta stage instead.
Use sort, near, or returnStoredSource Instead of $sort
For sorting numeric, date, string, boolean, UUID, and objectID fields, use the
sortoption with the$searchstage. To learn more, see Sort MongoDB Search Results.For sorting geo fields, use the near operator.
To sort other fields, use
$sortand returnStoredSource fields.
Avoid Use of $skip After $search
Using $skip and $limit to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the $search searchAfter or searchBefore options to paginate results. To learn more, see Paginate the Results.
To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:
$searchsearchAfterthe last result on Page 2$skipdocuments on Pages 3 and 4$limitresults 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.
Use $search Instead of $text or $regex
For applications that rely heavily on MongoDB $text and $regex queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search $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, $text, and MongoDB Search $search address your application's requirements.
If your application requires... | Use... | Because... |
|---|---|---|
Datastore to respect write concerns | ||
Cluster optimized for write performance | MongoDB Search indexes don't degrade cluster write performance. | |
Searching through large data sets | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. | |
Language awareness | MongoDB Search supports many language analyzers that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. | |
Case-insensitive text search | ||
Highlighting result text | MongoDB Search highlighting allows you to contextualize the documents in the results, which is essential for natural language queries. | |
Geospatial-aware search queries | MongoDB | |
Autocompletion of search queries | For autocomplete of characters (nGrams), MongoDB Search includes For autocomplete of words (wordGrams), MongoDB Search includes shingle token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. | |
Fuzzy matching on text input | MongoDB Search text and autocomplete operators support | |
Filtering based on multiple strings | MongoDB Search compound supports filtering based on multiple strings. | |
Relevance score sorted search | MongoDB Search uses the BM25 algorithm for determining the search relevance score of documents. It supports advanced configuration through | |
Partial indexes | MongoDB Search supports partial indexing by using a View with a | |
Patial match | MongoDB Search wildcard and autocomplete operators support partial match queries. | |
Single compound index on arrays | 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 | MongoDB Search supports synonyms 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 tutorial. | |
Faceting for counts | MongoDB Search provides fast counts of documents based on text criteria, and also supports faceted search for numbers and dates. To learn more, see How to Use Facets with MongoDB Search. | |
Extract metadata | MongoDB Search | |
Custom analyzers | MongoDB Search supports custom analyzers to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP or HTTPS URLs using custom analyzers. | |
Searching phrases or multiple words | MongoDB Search phrase operator supports searching for a sequence of terms. | |
Searching with regular expression | MongoDB Search provides improved performance when you use the MongoDB Search autocomplete operator instead. |
Tip
Use
$searchInstead of$textor$regex- describes how you can replace$textaggregation pipeline stage in your query with$searchto improve both the flexibility and performance of these queries.Use
$searchInstead of$textor$regex- describes how you can replace inefficient regex matching with$searchto improve the performance of text queries.
Learn More
Continue Learning
Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using explain and $search score details.
Duration: 5 Minutes
Consider Query Operators and Query Complexity
The complexity level of MongoDB Search queries and the type of 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 operator, or queries which use the regex (regular expression) or the wildcard operator, are resource-intensive.
Compound Queries
If your query includes multiple nested compound 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, range, and in in the filter clause to avoid unnecessary scoring operations.
Faceted Search
You can use the MongoDB Search facet (MongoDB Search Operator) 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.
Use $limit Before $facet
Using a $limit aggregation pipeline stage after a $facet aggregation pipeline stage might negatively impact query performance. To avoid performance bottlenecks, use $limit before $facet.
Example
{ { "$search": {...} }, { "$limit": 20 }, { "$facet": { "results": [], "totalCount": $$SEARCH_META } } }
For a demonstration, see the following examples:
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, $count, $match, or $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 operator with filter clauses. If you must use the $match stage in your aggregation pipeline, consider using the storedSource option to store only the fields that your $match condition needs. You can then use the $search returnStoredSource option to retrieve stored fields and avoid the mongod full document lookup.
Use facet Instead of $group
If you use $group to get basic counts for field aggregations, you can use facet (MongoDB Search Operator) inside the $search stage. If you need only metadata results, you can use facet (MongoDB Search Operator) inside inside the $searchMeta stage instead.
Use count Instead of $count
If you use $count to get a count of the number of documents, we recommend that you use count inside the $search or $searchMeta stage instead.
Use sort, near, or returnStoredSource Instead of $sort
For sorting numeric, date, string, boolean, UUID, and objectID fields, use the
sortoption with the$searchstage. To learn more, see Sort MongoDB Search Results.For sorting geo fields, use the near operator.
To sort other fields, use
$sortand returnStoredSource fields.
Avoid Use of $skip After $search
Using $skip and $limit to retrieve results non-sequentially might be slow if the results for your query are large. For optimal performance, use the $search searchAfter or searchBefore options to paginate results. To learn more, see Paginate the Results.
To return non-sequential results, such as jumping from page 2 to page 5, you can use the following pipeline stages:
$searchsearchAfterthe last result on Page 2$skipdocuments on Pages 3 and 4$limitresults 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.
Use $search Instead of $text or $regex
For applications that rely heavily on MongoDB $text and $regex queries, use the following recommendations to determine whether to refactor your applications or migrate your applications to MongoDB Search $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, $text, and MongoDB Search $search address your application's requirements.
If your application requires... | Use... | Because... |
|---|---|---|
Datastore to respect write concerns | ||
Cluster optimized for write performance | MongoDB Search indexes don't degrade cluster write performance. | |
Searching through large data sets | MongoDB Search uses an inverted index, which enables fast document retrieval at very large scales. | |
Language awareness | MongoDB Search supports many language analyzers that can tokenize (create searchable terms) languages, remove stopwords, and interpret diacritics for improved search relevance. | |
Case-insensitive text search | ||
Highlighting result text | MongoDB Search highlighting allows you to contextualize the documents in the results, which is essential for natural language queries. | |
Geospatial-aware search queries | MongoDB | |
Autocompletion of search queries | For autocomplete of characters (nGrams), MongoDB Search includes For autocomplete of words (wordGrams), MongoDB Search includes shingle token filter, which supports word-based autocomplete by concatenating adjacent words to create a single token. | |
Fuzzy matching on text input | MongoDB Search text and autocomplete operators support | |
Filtering based on multiple strings | MongoDB Search compound supports filtering based on multiple strings. | |
Relevance score sorted search | MongoDB Search uses the BM25 algorithm for determining the search relevance score of documents. It supports advanced configuration through | |
Partial indexes | MongoDB Search supports partial indexing by using a View with a | |
Patial match | MongoDB Search wildcard and autocomplete operators support partial match queries. | |
Single compound index on arrays | 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 | MongoDB Search supports synonyms 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 tutorial. | |
Faceting for counts | MongoDB Search provides fast counts of documents based on text criteria, and also supports faceted search for numbers and dates. To learn more, see How to Use Facets with MongoDB Search. | |
Extract metadata | MongoDB Search | |
Custom analyzers | MongoDB Search supports custom analyzers to suit your specific indexing requirements. For example, you can index and search email addresses and HTTP or HTTPS URLs using custom analyzers. | |
Searching phrases or multiple words | MongoDB Search phrase operator supports searching for a sequence of terms. | |
Searching with regular expression | MongoDB Search provides improved performance when you use the MongoDB Search autocomplete operator instead. |
Tip
Use
$searchInstead of$textor$regex- describes how you can replace$textaggregation pipeline stage in your query with$searchto improve both the flexibility and performance of these queries.Use
$searchInstead of$textor$regex- describes how you can replace inefficient regex matching with$searchto improve the performance of text queries.
Learn More
Continue Learning
Follow along with this video to learn how to understand, iterate, and improve your MongoDB Search results using explain and $search score details.
Duration: 5 Minutes