Indexes
On this page
Overview
Indexes are data structures that support the efficient execution of queries in MongoDB. They contain copies of parts of the data in documents to make queries more efficient.
Without indexes, MongoDB must scan every document in a collection to find the documents that match each query. These collection scans are slow and can negatively affect the performance of your application. By using an index to limit the number of documents MongoDB scans, queries can be more efficient and therefore return faster.
Query Coverage and Performance
When you execute a query against MongoDB, your query can include three parts:
query criteria that specify field(s) and value(s) you are looking for
options that affect the query's execution, such as read concern
projection criteria to specify the fields MongoDB should return (optional)
When all the fields specified in the query criteria and projection of a query are indexed, MongoDB returns results directly from the index without scanning any documents in the collection or loading them into memory.
For additional information on how to ensure your index covers your query criteria and projection, see the MongoDB manual articles on query coverage and index intersection.
Operational Considerations
To improve query performance, build indexes on fields that appear often in your application's queries and operations that return sorted results. Each index that you add consumes disk space and memory when active so you should track index memory and disk usage for capacity planning. In addition, when a write operation updates an indexed field, MongoDB also has to update the related index.
For more information on designing your data model and choosing indexes appropriate for your application, see the MongoDB server documentation on Indexing Strategies and Data Modeling and Indexes.
Index Types
MongoDB supports a number of different index types to support querying your data. The following sections describe the most common index types and provide sample code for creating each index type.
Single Field Indexes
Single field indexes are indexes that improve performance for queries that specify ascending or descending sort order on a single field of a document.
The following example uses the createIndex()
method to create an
ascending order index on the title
field in the movies
collection in
the sample_mflix
database.
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create an ascending index on the "title" field in the // "movies" collection. const result = await movies.createIndex({ title: 1 }); console.log(`Index created: ${result}`);
The following is an example of a query that would be covered by the index created above.
const query = { title: "Batman" } const sort = { title: 1 }; const projection = { _id: 0, title: 1 }; const cursor = movies .find(query) .sort(sort) .project(projection);
To learn more, see Single Field Indexes.
Compound Indexes
Compound indexes are indexes that improve performance for queries that specify ascending or descending sort order for multiple fields of a document. You must specify the direction (ascending or descending) for each field in the index.
The following example uses the createIndex()
method to create a compound
index on the type
and genre
fields in the movies
collection in the
sample_mflix
database.
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create an ascending index on the "type" and "genre" fields // in the "movies" collection. const result = await movies.createIndex({ type: 1, genre: 1 }); console.log(`Index created: ${result}`);
The following is an example of a query that would be covered by the index created above.
const query = { type: "movie", genre: "Drama" }; const sort = { type: 1, genre: 1 }; const projection = { _id: 0, type: 1, genre: 1 }; const cursor = movies .find(query) .sort(sort) .project(projection);
To learn more, see Compound Indexes.
Multikey Indexes (Indexes on Array Fields)
Multikey indexes are indexes that improve the performance of queries on fields that contain array values.
You can create a multikey index on a field with an array value by
calling the createIndex()
method. The following code creates an ascending
index on the cast
field in the movies
collection of the
sample_mflix
database:
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create a multikey index on the "cast" field const result = await movies.createIndex({ cast: 1 });
The following code queries the multikey index to find
documents with a cast
field value that contains "Viola Davis":
const query = { cast: "Viola Davis" }; const projection = { _id: 0, cast: 1 , title: 1 }; const cursor = movies .find(query) .project(projection);
Multikey indexes behave differently from non-multikey indexes in terms of query coverage, index bound computation, and sort behavior. For a full explanation of multikey indexes, including a discussion of their behavior and limitations, refer to the Multikey Indexes page in the MongoDB Server manual.
Clustered Indexes
Clustered indexes are indexes that improve the performance of insert, update, and delete operations on clustered collections. Clustered collections store documents ordered by the clustered index key value.
To create a clustered index, specify the clusteredIndex
option in
the CollectionOption
. The clusteredIndex
option must specify the
_id
field as the key and the unique field as true
.
The following example uses the createCollection()
method to create a
clustered index on the _id
field in the vendors
collection of the
tea
database.
const db = client.db('tea'); await db.createCollection('ratings', { clusteredIndex: { key: { _id: 1 }, unique: true } });
To learn more, see Clustered Indexes and Clustered Collections.
Text Indexes
Text indexes support text search queries on string content. These indexes can include any field whose value is a string or an array of string elements.
MongoDB supports text search for various languages, so you can specify the default language as an option when creating the index. You can also specify a weight option to prioritize certain text fields in your index. These weights denote the significance of fields relative to the other indexed fields.
To learn more about text searches, see our guide on text search queries.
The following example uses the createIndex()
method to perform the
following actions:
Create a
text
index on thetitle
andbody
fields in theblogPosts
collectionSpecify
english
as the default languageSet the field weight of
body
to10
andtitle
to3
const myDB = client.db("testDB"); const myColl = myDB.collection("blogPosts"); // Create a text index on the "title" and "body" fields const result = await myColl.createIndex( { title: "text", body: "text" }, { default_language: "english" }, { weights: { body: 10, title: 3 } } );
The following query uses the text index created in the preceding code:
const query = { $text: { $search: "life ahead" } }; const projection = { _id: 0, title: 1 }; const cursor = myColl.find(query).project(projection);
To learn more about text indexes, see Text Indexes in the Server manual.
Geospatial Indexes
MongoDB supports queries of geospatial coordinate data using 2dsphere indexes. With a 2dsphere index, you can query the geospatial data for inclusion, intersection, and proximity. For more information on querying geospatial data with the MongoDB Node.js driver, read our Search Geospatial guide.
To create a 2dsphere index, you must specify a field that contains only GeoJSON objects. For more details on this type, see the MongoDB server manual page on GeoJSON objects.
The location.geo
field in following sample document from the
theaters
collection in the sample_mflix
database is a GeoJSON Point
object that describes the coordinates of the theater:
{ "_id" : ObjectId("59a47286cfa9a3a73e51e75c"), "theaterId" : 104, "location" : { "address" : { "street1" : "5000 W 147th St", "city" : "Hawthorne", "state" : "CA", "zipcode" : "90250" }, "geo" : { "type" : "Point", "coordinates" : [ -118.36559, 33.897167 ] } } }
The following example uses the createIndexes()
method to create a
2dsphere
index on the location.geo
field in the theaters
collection in the sample_mflix
database to enable geospatial searches.
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create a 2dsphere index on the "location.geo" field in the "theaters" collection. const result = await movies.createIndex({ "location.geo": "2dsphere" }); console.log(`Index created: ${result}`);
MongoDB also supports 2d
indexes for calculating distances on a
Euclidean plane and for working with the "legacy coordinate pairs" syntax
used in MongoDB 2.2 and earlier. To learn more, see
Geospatial Queries.
Unique Indexes
Unique indexes ensure that the indexed fields do not store duplicate
values. By default, MongoDB creates a unique index on the _id
field
during the creation of a collection. To create a unique index, specify the
field or combination of fields that you want to prevent duplication on and
set the unique
option to true
.
The following example uses the createIndex()
method to create a unique
index on the theaterId
field in the theaters
collection of the
sample_mflix
database.
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create a unique index on the "theaterId" field in the "theaters" collection. const result = await movies.createIndex({ theaterId: 1 }, { unique: true }); console.log(`Index created: ${result}`);
If you attempt to perform a write operation that stores a duplicate value that violates the unique index, MongoDB will throw an error that resembles the following:
E11000 duplicate key error index
To learn more, see Unique Indexes.
List Indexes
You can use the listIndexes()
method to list all of the indexes for
a collection. The listIndexes() method takes an optional
ListIndexesOptions
parameter. The listIndexes()
method returns an object of type
ListIndexesCursor.
The following code uses the listIndexes()
method to list all the
indexes in a collection:
const result = await collection.listIndexes().toArray(); console.log("Existing indexes:\n"); for(const doc in result){ console.log(doc); }