MongoDB Index Tutorial – Create Index & MongoDB Index Types

Indexes are important aspects while reading or fetching the documents. If we do not have indexes set up, we must scan every document of the collection to find and fetch the document that matches the query statement. Doing full scan degrades the performance of the application and is very inefficient considering when we are dealing with large volume of data and processing it. But the good news is that MongoDB provides a very easy and efficient way to implement indexes. If an appropriate index exists for a query, MongoDB can use the index to limit the number of documents it must inspect and hence rudeces the execution time. In this MongoDB index tutorial, we will see how to create indexes, show indexes, and use indexes.

Before proceeding with tutorial, let’s revise what indexes are. In brief, Indexes are special data structures. They store a small portion of the data set which can be easily traversed. It can be the value of a specific field or set of fields, ordered by the value of the field as specified while creating the index.

Note: MongoDB creates a unique index on the _id field during the creation of a collection. The _id index prevents from inserting two documents with the same value for the _id field. We cannot drop this index.

Also, MongoDB indexes use a B-tree data structure.

MongoDB Index Tutorial – Create Index (createIndex ())

 

  • MongoDB createIndex () method

In order to create indexes in MongoDB, we have createIndex() method. Earlier, we had ensureIndex() method to create index but it is Deprecated since version 3.0.0. db.collection.ensureIndex() is now an alias for db.collection.createIndex().

Below is the syntax:

db.collection.createIndex(Keys, Options)

where,

Keys :=  A type of document that contains the field and value pairs where the field is the index key and the value describes the type of index for that field. For an ascending index on a field, specify a value of 1; for descending index, specify a value of -1

Options := (Optional) A document that contains a set of options that controls the creation of the index. Few options are:

  • background: It builds the index in the background so the operation does not block other database activities. Specify true to build in the background. The default value is false.
  • unique: It creates a unique index so that the collection will not accept insertion or update of documents where the index key value matches an existing value in the index.
  • expireAfterSeconds: Specifies a value, in seconds, to control how long MongoDB retains documents in this collection.
  • name: The name of the index. If unspecified, MongoDB generates an index name by concatenating the names of the indexed fields and the sort order.
  • v: (Version Number) The default index version depends on the version of MongoDB running when creating the index.

Let’s try it on Mongo shell.

Suppose we have following collection with following fields/documents

MongoDB Collection:

Let’s create index on field “blog” in ascending order using createIndex() method.

MongoDB Index Tutorial - Create Index

Here, you can see index is created. Another thing to note here is, there are two parameters – numIndexesBefore and numIndexesAfter.

You can see before creating any index we had 1 index created by default (i.e. for _id field), so – numIndexesBefore:1.

After creating index on ‘blog’, index count became 2, so –

numIndexesAfter:2.

MongoDB Index Tutorial – MongoDB Indexes Types


There are many index types provided by MongoDB to support specific types of data and queries. Below are a few of them:

  • Single Field Index

MongoDB supports creating user-defined indexes on a single field of the document in either ascending or descending order. (in addition to _id index)

//Here we are indexing student_id in descending order

          db.collection.createIndex( { student_id: -1 } )

Value of 1 specifies an index that orders items in ascending order. A value of -1 specifies an index that orders items in descending order

          *Note:  You can also create index on Embedded document/fields.

For example: Let’s assume we have following collection named as ‘tutorialsjar’:

{

  "_id": ObjectId("790c04a4ad233577f97d141"),

  "name": "TutorialsJar"

  "location": { country: "India", state: "Punjab" }

}

Now, in order to create index on state (in ascending order), we can write following:

db.tutorialsjar.createIndex( { "location.state": 1 } )
  • Compound Index

Similar to single field index, you can create compound index as well i.e. on multiple fields in a document.

E.g. We have ‘school’ collection with classes and students fields.

db.school.createIndex( { class_id: 1, student_id: -1 } )

Remember that the order of the fields listed in a compound index is important. The index will contain references to documents sorted first by the values of the class_id field (in ascending order) and, within each value of the class field, sorted by values of the student_id field (in descending order).

  • Multikey Index

If you want to index content stored in arrays, MongoDB provides Multikey Indexes. When you index a field that holds an array value, MongoDB creates separate index entries for every element of the array which allow queries to select documents that contain arrays by matching on element or elements of the arrays.

E.g. Let’s say we have following document in same collection ‘tutorialsjar’:

{ _id: 1

name: ‘Mohit’,

tags: [‘Blogging, Cricket, Music’],

color:’red’,

location:[‘India’,’US’, ‘Canada’]

}

Syntax:

db.tutorialsjar.createIndex({‘tags’:1, ‘location’:1})

** Key note here is you cannot create index on fields which are both arrays.

For example, in above example, you can create index on (tags) OR (tags, color) but NOT on (tags, location) (As both tags and location are arrays)

One interesting thing is, let’s say we have index on (tags, color). If you insert new document with tags as scalar and color as array then it is possible and it will not throw any error such as:

{

tags: ‘photography’,

color: [‘red’,’green’,’blue’]

}
  • Unique Index

The unique property for an index causes MongoDB to reject duplicate values for the indexed field. To create a unique index on a field that already has duplicate values. Other than the unique constraint, unique indexes are functionally interchangeable with other MongoDB indexes.

E.g.

db.tutorialsjar.createIndex({‘name’:1},{unique:true});

Here, ‘name’ should not have duplicate values but only unique value. If you insert the same value for ‘name’ again, it will throw an error.

  • Sparse Index

The sparse property of an index ensures that the index only contains entries for documents that have the indexed field. The index skips documents that do not have the indexed field. We can combine the sparse index option with the unique index option to reject documents that have duplicate values for a field but ignore documents that do not have the indexed key.

E.g.:

db.tutorialsjar.createIndex({‘name’:1},{unique:true, sparse:true});

Because in few cases, we might not have name field (only personal ID is there). Hence, it will have NULL which will violate unique constraint. So, using Sparse index with Unique index is efficient.

  •  Geospatial Index

MongoDB supports Geospatial index for querying geospatial coordinate data. There are two indexes:

  1. 2d indexes – Uses planar geometry when returning results (Use a 2dindex for data stored as points on a two-dimensional plane).

Suppose we have location field with some X & Y coordinates such as:

{“Location”: [X,Y]}

We can create index like:

db.tutorialsjar.createIndex({“location”:”2d”});

In order to find documents:

db.tutorialsjar.find({“location”:{$near:[50,50]}});

If you are not much confident with Find command, youc an read my other article on MongoDB Find Command.

2)  2d sphere indexes – Uses spherical geometry to return results. (Calculate geometries on an earth-like sphere. 2dsphereindex supports all MongoDB geospatial queries: queries for inclusion, intersection and proximity.)

E.g. (taken from MongoDB site)

db.places.insert(

   {

      loc : { type: "Point", coordinates: [ -73.97, 40.77 ] },

      name: "Central Park",

      category : "Parks"

   }

)

db.places.insert(

   {

      loc : { type: "Point", coordinates: [ -73.88, 40.78 ] },

      name: "La Guardia Airport",

      category : "Airport"

   }

)

Syntax to create index:

db.places.createIndex( { loc : "2dsphere" } );

**You can also create compound index with non-geospatial index keys.

db.places.createIndex( { loc : "2dsphere" , category : 1} )

A compound 2dsphere index does not require the location field to be the first field indexed. You can also write as:

db.places.createIndex( { category : 1 , loc : "2dsphere" } ) ;

Now, in order to find documents using 2dsphere indexes:

db.tutorialsjar.find({“location”: {$near:{$geometry:{type:”point”, coordinates:[-122.16,47.78]},$maxDistance: 2000)}}}).pretty();
  • Text Index

 MongoDB provides text indexes to support text search queries on string content. text indexes can include any field whose value is a string or an array of string elements.

Note that a collection can have at most one text index.

E.g. Suppose we have ‘Animal’ collection with the following documents:

{_id:1, “words”: ”dogs and cats”, “seq”:1}

{_id:2, “words”: ”dogs and cows”,”seq”:2 }

In order to create an index:

db.animal.createIndex({“words”:’text’});

To find documents:

db.animal.find({$text:{$search:”dogs”}});

** Capitalization also does not make any difference. It will search same for ‘Dog’

  • TTL Index (Total Time To Live Index)

TTL indexes are a special type of indexes which can be used to automatically remove documents from a collection after a certain amount of time. Few documents we might not need after some period of time such as logs data, session information, audit data, machine-generated logs etc. So, in order to remove these type of documents, we can use MongoDB TTL indexes.

Syntax:

db.auditlog.createIndex( { "lastAuditDate": 1 }, { expireAfterSeconds: 3600 } );

MongoDB index Tutorial – List All Indexes or Show Indexes or Get Indexes


MongoDB provides getIndexes() method to return a list of all indexes on a collection.

Syntax:

db.collection.getIndexes()

For example, to view all indexes on the tutorialsjar collection, run the following command:

db.tutorialsjar.getIndexes();

MongoDB Index Tutorial - Show Index

You can see there are 2 indexes created on this collection but we had created only 1 index on ‘blog’. However, you can see there is another index created on _id by default.

If there is no index created on collection, by default it will return 1 index (i.e. for _id field which is by default indexed)

MongoDB Drop Indexes or Remove Indexes


MongoDB provides two methods for removing indexes from a collection:

  • dropIndex()

To remove a specific index, use db.collection.dropIndex().

For example, the following operation removes an index on the name field in the tutorialsjar colelction:

db.tutorialsjar.dropIndex( { "name": 1 } );
  • dropIndexes()

To remove all indexes from collection, use db.collection.dropIndexes().

For example, the following command removes all indexes from the ‘tutorialsjar’ collection:

db.tutorialsjar.dropIndexes();

MongoDB Index Tutorial - Drop Indexes

“nIndexesWas”: 2 shows total indexes in collection (including _id field index) before dropping indexes.

Note that it does not drop index created on _id field. You can see message – “msg”: “non-_id indexes dropped for collection.”

That is all in this MongoDB Index Tutorial article. I hope you found something new to learn here. Do not forget to share it with your friends.

Is there anything else we should have included in this MongoDB indexing article? Do let us know in the comment section below.

Mohit Arora
Follow me