Docs Menu

Docs HomeDevelop ApplicationsMongoDB DriversGo Driver

Indexes

On this page

  • Overview
  • Query Coverage and Performance
  • Operational Considerations
  • Index Types
  • Single Field Indexes
  • Compound Indexes
  • Multikey Indexes (Indexes on Array Fields)
  • Clustered Indexes
  • Text Indexes
  • Geospatial Indexes
  • Unique Indexes
  • Remove an Index
  • Additional Information
  • API Documentation

In this guide, you can learn how to use indexes in the MongoDB Go Driver.

Indexes support the efficient execution of queries in MongoDB. Without indexes, MongoDB scans every document in a collection (a collection scan) to find documents that match your query. Collection scans are slow and can negatively affect the performance of your application. With an appropriate index, MongoDB limits the number of documents it inspects.

Tip

You can also use indexes in update operations, delete operations, and certain aggregation pipeline stages.

A query in MongoDB can contain the following elements:

Element
Necessity
Purpose
Query
Required
Specify the fields and values you're looking for.
Options
Optional
Specify how the query executes.
Projection
Optional
Specify the fields that MongoDB returns.
Sort
Optional
Specify the order MongoDB returns documents.

When you specify these elements in the same index, MongoDB returns results directly from the index, also called a covered query.

Important

Sort Criteria

Your sort criteria must match or invert the order of the index.

Consider an index on the field name in ascending order (A-Z) and age in descending order (9-0):

name_1_age_-1

MongoDB uses this index when you sort your data by either:

  • name ascending, age descending

  • name descending, age ascending

Specifying a sort order of name and age ascending or name and age descending requires an in-memory sort.

To learn how to ensure your index covers your query criteria and projection, see Query Coverage.

To improve your query performance, create indexes on fields that appear often in your queries and operations that return sorted results. Track index memory and disk usage for capacity planning since each index that you add consumes disk space and memory. In addition, when a write operation updates an indexed field, MongoDB also must update the related index.

Since MongoDB supports dynamic schemas, your application can query against fields with unknown or arbitrary names. MongoDB 4.2 introduced wildcard indexes to help support these queries. Wildcard indexes are not designed to replace workload-based index planning.

To learn more about designing your data model and choosing indexes appropriate for your application, see Indexing Strategies and Data Modeling and Indexes.

MongoDB supports several index types to support querying your data. The following sections describe and show how to create the most common index types. To view a full list of index types, see Indexes.

Single field indexes holds a reference to a field within a collection's documents.

This index improves single field queries and sort performance, and supports TTL indexes that automatically remove documents from a collection after a certain amount of time.

Note

The _id_ index is an example of a single field index. This index is automatically created on the _id field when you create a new collection.

The following example creates an index in ascending order on the title field in the sample_mflix.movies collection:

coll := client.Database("sample_mflix").Collection("movies")
indexModel := mongo.IndexModel{
Keys: bson.D{{"title", 1}},
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

Compound indexes hold a reference to multiple fields within a collection's documents. This index improves query and sort performance.

The following example creates a compound index on the fullplot and title fields in the sample_mflix.movies collection:

coll := client.Database("sample_mflix").Collection("movies")
indexModel := mongo.IndexModel{
Keys: bson.D{
{"fullplot", -1},
{"title", 1}
}
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

Multikey indexes use the same syntax as a single field index and a compound index. This index improves the performance of queries that specify an array field as an index.

The following example creates a multikey index on the cast field in the sample_mflix.movies collection:

coll := client.Database("sample_mflix").Collection("movies")
indexModel := mongo.IndexModel{
Keys: bson.D{{"cast", -1}}
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

Clustered indexes 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 clustered index option with the _id field as the key and the unique field as true when you create your collection.

The following example creates a clustered index on the _id field in the db.tea collection:

db := client.Database("db")
cio := bson.D{{"key", bson.D{{"_id", 1}}}, {"unique", true}}
opts := options.CreateCollection().SetClusteredIndex(cio)
db.CreateCollection(context.TODO(), "tea", opts)

Text indexes support text search queries on string content. This index requires a string field or an array of strings. MongoDB supports text search for several languages. You can specify the default language as an option when creating the index.

A collection can only contain one text index. If you want to create a text index for multiple text fields, you must create a compound index. The text search runs on all the text fields within the compound index.

Tip

Text indexes differ from the more powerful Atlas full text search indexes. We recommend Atlas search for Atlas users.

The following example creates a text index on the plot field with italian as the default language in the sample_mflix.movies collection:

coll := client.Database("sample_mflix").Collection("movies")
indexModel := mongo.IndexModel{Keys: bson.D{{"plot", "text"}, {"default_language", "italian"}}}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

MongoDB supports queries containing geospatial coordinate data by using 2dsphere indexes. A 2dsphere index must be in a GeoJSON objects field.

This index allows you to perform the following:

  • Query geospatial data for inclusion, intersection, and proximity.

  • Calculation of distances on a Euclidean plane and for working with the "legacy coordinate pairs" syntax used in MongoDB 2.2 and earlier.

The location.geo field in a document from the sample_mflix.theaters collection 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 creates a 2dsphere index on the location.geo field:

Important

Attempting to create a geospatial index on a field that is covered by a geospatial index results in an error.

indexModel := mongo.IndexModel{
Keys: bson.D{{"location.geo", "2dsphere"}}
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

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 creates a unique, descending index on the theaterId field:

indexModel := mongo.IndexModel{
Keys: bson.D{{"theaterId", -1}},
Options: options.Index().SetUnique(true),
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)

You can remove any unused index except the default unique index on the _id field. To remove an index, pass the name of your index to the DropOne() method.

The following example removes an ascending index on the title field in the sample_mflix.movies collection:

coll := client.Database("sample_mflix").Collection("movies")
res, err := coll.Indexes().DropOne(context.TODO(), "title_1")
if err != nil {
panic(err)
}
fmt.Println(res)

To learn more about the indexes mentioned, see the following guides:

To learn more about the operations mentioned, see the following guides:

To learn more about any of the methods discussed in this guide, see the following API Documentation:

←  AggregationTransactions →