Docs Menu

Optimize Queries With Indexes

In this guide, you can learn how to use indexes with Mongoid. Indexes can improve the efficiency of queries by limiting the number of documents MongoDB needs to scan. If your application is repeatedly running queries on certain fields, you can create an index on those fields to improve query performance.

The following sections in this guide describe how to declare and create different types of indexes using Mongoid. The examples use the Restaurant model, which maps to the restaurants collection in the sample_restaurants database. To learn how to connect to this database and collection using Mongoid, see the Quick Start - Ruby on Rails or Quick Start - Sinatra guides.

When using Mongoid, you can declare your index using the index macro and then create it using the create_indexes command.

The following code example shows how to declare and create an ascending index named cuisine_index on the cuisine field in the Restaurant class:

class Restaurant
include Mongoid::Document
field :name, type: String
field :cuisine, type: String
field :borough, type: String
index({ cuisine: 1}, { name: "cuisine_index", unique: false })
end
Restaurant.create_indexes

The index macro defines the index you want to create and the create_indexes command creates it in the restaurants collection.

When defining an index, the first hash object contains the field you want to index and its direction. 1 represents an ascending index, and -1 represents a descending index. The second hash object contains index options. To learn more about index options, see the API Documentation section.

You can use aliased field names in index definitions. For example, the following code creates an index on the b field, which is an alias of the borough field:

class Restaurant
include Mongoid::Document
field :borough, as: :b
index({ b: 1}, { name: "borough_index" })
end

You can define an index on embedded document fields. The following code example shows how to declare an ascending index on the street field, which is embedded within the address field in the Restaurant model.

class Address
include Mongoid::Document
field :street, type: String
end
class Restaurant
include Mongoid::Document
embeds_many :addresses
index({"addresses.street": 1})
end

You can define a compound index on multiple fields. The following code example shows how to declare a compound index that is ascending on the borough field and descending on the name field.

class Restaurant
include Mongoid::Document
field :name, type: String
field :borough, type: String
index({borough: 1, name: -1}, { name: "compound_index"})
end

You can define a 2dsphere index on fields that contain GeoJSON objects or coordinate pairs. The following example defines a 2dsphere index on a field that contains GeoJSON objects:

class Restaurant
include Mongoid::Document
field :location, type: Array
index({location: "2dsphere"}, { name: "location_index"})
end

For more information on 2dsphere indexes, see the 2dsphere guide in the MongoDB Server manual.

For more information on the GeoJSON type, see the GeoJSON Objects guide in the MongoDB Server manual.

You can define a sparse index on fields that are not present in all documents. The following code example defines a sparse index on the borough field:

class Restaurant
include Mongoid::Document
field :name, type: String
field :cuisine, type: String
field :borough, type: String
index({ borough: 1}, { sparse: true })
end

For more information on sparse indexes, see the Sparse Indexes guide in the MongoDB Server manual.

You can define multiple indexes within your model and create them using a single create_indexes call. The following example shows how to create multiple indexes at the same time:

class Restaurant
include Mongoid::Document
field :name, type: String
field :cuisine, type: String
field :borough, type: String
index({ name: 1})
index({ cuisine: -1})
end
Restaurant.create_indexes

You can drop all indexes in your collection. The following example drops all indexes in the Restaurant model:

Restaurant.remove_indexes

Note

Default Index

MongoDB creates a default index on the _id field during the creation of a collection. This index prevents clients from inserting two documents with the same values for the _id field. You cannot drop this index.

You can declare and manage Atlas Search indexes using Mongoid.

To declare a search index, use the search_index macro within your model. To create the search indexes declared within a model, use the create_search_indexes command. The following code example shows how to declare and create an Atlas Search index named my_search_index. The index is on the name and cuisine fields and is dynamic.

class Restaurant
include Mongoid::Document
field :name, type: String
field :cuisine, type: String
field :borough, type: String
search_index :my_search_index,
mappings: {
fields: {
name: {
type: "string"
},
cuisine: {
type: "string"
}
},
dynamic: true
}
end
Restaurant.create_search_indexes

To learn more about the syntax for creating an Atlas Search index, see the Create an Atlas Search Index guide in the MongoDB Atlas documentation.

To remove an Atlas Search index, use the remove_search_indexes command. The following code example shows how to remove an Atlas Search index from the restaurants collection:

Restaurant.remove_search_indexes

You can enumerate through all Atlas Search indexes in your collection by using the search_indexes command. The following example enumerates through all Atlas Search indexes in the restaurants collection and prints out their information:

Restaurant.search_indexes.each { |index| puts index }

To learn more about using indexes in Mongoid, see the Mongoid::Indexable::ClassMethods documentation.

To learn more about index options, see the Mongoid::Indexable::Validators::Options documentation.

To learn more about using Atlas Search indexes in Mongoid, see the Mongoid::SearchIndexable::ClassMethods documentation.