An index covers a query when the index contains all of the fields scanned by the query. A covered query scans the index and not the collection, which improves query performance.
Indexes can also partially support queries if a subset of the fields queried are indexed.
About this Task
A single collection can have a maximum of 64 indexes. However, too many indexes can degrade performance before that limit is reached. For collections with a high write-to-read ratio, indexes can degrade performance because each insert must also update any indexes.
Steps
Identify common queries
To identify common query patterns in your application, use the
$queryStats aggregation stage. $queryStats reports
metrics for query shapes, which group
queries based on shared fields.
Create indexes to support common queries
After you know which fields your application frequently queries, you can create indexes to support queries on those fields. For more information, see Examples.
Analyze index use
After your application begins using indexes, you can analyze your indexes' effectiveness. To see index statistics and usage, you can:
Use the
$indexStatsaggregation stage.For MongoDB Atlas deployments, view Indexes in the Atlas UI.
Consider deleting unused indexes to improve application performance. For more information, see Remove Unnecessary Indexes.
Repeat this procedure periodically to ensure that your indexes support your current workload.
Examples
The examples on this page use data from the sample_mflix sample dataset. For details on how to load this dataset into your self-managed MongoDB deployment, see Load the sample dataset. If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.
Note
Documents in the movies collection contain additional fields not
shown here.
Create a Single-Key Index
If your application only queries on a single key in a given collection,
then you need to create a single-key index for that collection. For
example, you can create an index on title in the movies
collection:
db.movies.createIndex( { title: 1 } )
This index supports this query:
db.movies.find( { title: 'Mulholland Drive' } )
Create a Compound Index
If your application performs queries on both a single key and multiple
keys, a compound index is more efficient
than a single-key index. For example, you can create an index on the
year, runtime, and title fields:
db.movies.createIndex( { year: 1, runtime: 1, title: 1 } )
Index Prefixes
A compound index supports queries on index prefixes, which are the beginning subsets of indexed fields. For example, the preceding index supports this query:
db.movies.find( { year: 2012, runtime: { $gt: Decimal128( "120" ) } }, { title: 1 } )
For more information and performance considerations on index prefixes, see Index Prefixes.
Create Indexes to Support Text Search
For data hosted on MongoDB, you can support full-text search with MongoDB Search indexes. To learn more, see Create a MongoDB Search Index.
For self-managed (non-Atlas) deployments, MongoDB provides a text
index type that supports searching for string content in a collection.
To learn more about self-managed text indexes, see
Text Indexes on Self-Managed Deployments.
Create Vector Search Indexes
Vector Search Indexes support queries on vector embeddings. To create Vector Search Indexes, see Index Fields for Vector Search.
Index Use and Collation
To use an index for string comparisons, an operation must also specify the same collation. If an operation specifies a different collation than the index specifies, the index cannot support string comparisons on the indexed fields.
Warning
Collation-aware index keys might be larger than index keys for indexes without collation because indexes that are configured with collation use ICU collation keys to achieve sort order.
Use the following code to create an index on the movies collection of the
sample_mflix database with the collation locale "fr" for string
comparisons:
db.movies.createIndex( { title: 1 }, { collation: { locale: "fr" } } )
The following query, which specifies the same collation as the index, can use the index:
db.movies.find( { title: "Les Misèrables" }, { title: 1, year: 1 } ).collation( { locale: "fr" } )
However, the following query operation, which by default uses the
"simple" binary collator, cannot use the index and requires a COLLSCAN.
db.movies.find( { title: "Les Misèrables" }, { title: 1 , year: 1 } )
For a compound index where the index prefix keys are not strings, arrays, and embedded documents, an operation that specifies a different collation can still use the index to support comparisons on the index prefix keys.
For example, you can use the following code to create a compound index on the
movies collection of the sample_mflix database specifying the
numeric fields year and metacritic and the string field title.
The index also specifies the collation locale "fr" for string
comparisons:
db.movies.createIndex( { year: 1, metacritic: 1, title: 1 }, { collation: { locale: "fr" } } )
The following operations, which use "simple" binary collation
for string comparisons, can use the index:
db.movies.find( { year: 2012 }, { title: 1, year: 1, metacritic: 1 } ).sort( { title: 1 } )
db.movies.find( { year: 2012, metacritic: { $gt: Decimal128( "50" ) } }, { title: 1, year: 1, metacritic: 1 } ).sort( { title: 1 } )
The following operation, which uses "simple" binary collation
for string comparisons on the indexed title field, can use
the index to fulfill only the year: 2012 portion of the query:
db.movies.find( { year: 2012, title: "Les Misèrables" }, { year: 1, title: 1 } )
To confirm whether a query used an index, run the query with the
explain() option.
Important
Matches against document keys, including embedded document keys, use simple binary comparison. This means that a query for a key like "type.café" will not match the key "type.cafe", regardless of the value you set for the strength parameter.