Navigation

Indexes

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 (e.g. 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 and Compound 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 db = client.db("sample_mflix");
    const movies = db.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 = { title: 1 };

    const cursor = movies
      .find(query)
      .sort(sort)
      .project(projection);

See the MongoDB server manual section on single field indexes for more information.

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 db = client.db("sample_mflix");
    const movies = db.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 = { type: 1, genre: 1 };

    const cursor = movies
      .find(query)
      .sort(sort)
      .project(projection);

See the MongoDB server manual section on Compound indexes for more information.

Multikey Indexes (Indexes on Array Fields)

Multikey indexes are indexes that improve performance for queries that specify ascending or descending indexes on fields that contain an array value. You can define a multikey index using the same syntax as a single field or compound index.

The following example use the createIndex() method to create an ascending index on the cast field (array of names) in the movies collection in the sample_mflix database.

    const db = client.db("sample_mflix");
    const movies = db.collection("movies");

    // Create a multikey index on the "cast" array field
    // in the "movies" collection.
    const result = await movies.createIndex({ cast: 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 = { cast: "Burt Reynolds" };
    const sort = { cast: 1, genre: 1 };
    const projection = { cast: 1 };

    const cursor = movies
      .find(query)
      .sort(sort)
      .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 manual.

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. You can specify the default language as an option when creating the index. Read our guide on text search queries for more information.

The following example uses the createIndex() method to create a text index on the fullplot field in the movies collection in the sample_mflix database and specifies english as the default language.

    const db = client.db("sample_mflix");
    const movies = db.collection("movies");

    // Create a text index on the "fullplot" field in the
    // "movies" collection.
    const result = await movies.createIndex({ fullplot: "text" }, { default_language: "english" });
    console.log(`Index created: ${result}`);

The following is an example of a query that would be covered by the index created above. Note that the sort is omitted because text indexes do not contain sort order.

    const query = { $text: { $search: "java coffee shop" } };
    const projection = { fullplot: 1 };
    const cursor = movies
      .find(query)
      .projection(projection);

For a full explanation of text search with MongoDB, refer to Text Indexes in the MongoDB 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 db = client.db("sample_mflix");
    const movies = db.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. See the Geospatial Queries page in the MongoDB server manual for more further information.

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 db = client.db("sample_mflix");
    const movies = db.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

Refer to the Unique Indexes page in the MongoDB server manual for more information.