Docs Menu
Docs Home
/ /

Create Indexes to Support Your Queries

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.

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.

1

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.

2

After you know which fields your application frequently queries, you can create indexes to support queries on those fields. For more information, see Examples.

3

After your application begins using indexes, you can analyze your indexes' effectiveness. To see index statistics and usage, you can:

  • Use the $indexStats aggregation 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.

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.

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' } )

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 } )

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.

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.

Vector Search Indexes support queries on vector embeddings. To create Vector Search Indexes, see Index Fields for Vector Search.

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.

Back

Apply Patterns

On this page