Indexes
On this page
Overview
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.
Query Coverage and Performance
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 should return. |
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
descendingname
descending,age
ascending
Specifying a sort order of name
and age ascending or name and age
descending would require an in-memory sort.
To learn how to ensure your index covers your query criteria and projection, see Query Coverage.
Operational Considerations
To improve your query performance, create indexes on fields that appear often in your queries and operations that return sorted results. You should 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 has to update the related index.
Since MongoDB supports dynamic schemas, your application can query against fields with currently 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.
Index Types
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
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 TLL 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.
Example
The following example creates an index in ascending order on the
title
field in the sample_mflix.movies
collection:
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
Compound indexes hold a reference to multiple fields within a collection's documents. This index improves query and sort performance.
Example
The following example creates a compound index on the fullplot
and
title
fields in the sample_mflix.movies
collection:
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 (Indexes on Array Fields)
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.
Example
The following example creates a multikey index on the cast
field in the sample_mflix.movies
collection:
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
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.
Example
The following example creates a clustered index on the _id
field in
the tea.vendors
collection:
db := client.Database("tea") cio := bson.D{{"key", bson.D{{"_id", 1}}}, {"unique", true}} opts := options.CreateCollection().SetClusteredIndex(cio) db.CreateCollection(context.TODO(), "vendors", opts)
Text Indexes
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 need to 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. Atlas users should use Atlas search.
Example
The following example creates a text index on the plot
field with
italian
as the default language in the sample_mflix.movies
collection:
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)
Geospatial Indexes
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 perfrom 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.
Example
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
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
.
Example
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)
Remove an Index
You can remove any unused index except the default unique index on the
_id
field. To removve 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:
res, err := coll.Indexes().DropOne(context.TODO(), "title_1") if err != nil { panic(err) } fmt.Println(res)
Additional Information
To learn more about the indexes mentioned, see the following guides:
To learn more about the operations mentioned, see the following guides:
API Documentation
To learn more about any of the methods discussed in this guide, see the following API Documentation: