Indexing in MongoDB

Understanding the importance of indexing for query performance and how to create and manage indexes on collections.


MongoDB Essentials: Indexes

Creating Indexes in MongoDB

Indexes are essential for optimizing query performance in MongoDB. Without indexes, MongoDB must scan every document in a collection to find documents matching your query, which can be very slow for large collections. Indexes allow MongoDB to quickly locate the documents matching your query criteria.

What are Indexes?

Indexes are special data structures that store a small portion of your collection's data in an easy to traverse form. The index stores the value of a specific field or set of fields, ordered by the value of the field.

Why Use Indexes?

  • Improve Query Performance: Significantly speed up read operations (find, aggregate, etc.).
  • Efficient Sorting: Enable faster sorting of query results.
  • Enforce Uniqueness: Create unique indexes to prevent duplicate values in a field.

Creating Indexes using createIndex()

The primary way to create indexes in MongoDB is using the createIndex() method on a collection.

Syntax

 db.collectionName.createIndex(keys, options) 
  • collectionName: The name of the collection where you want to create the index.
  • keys: A document specifying the fields to index and the index type. For a single-field index, use { fieldName: 1 } (ascending order) or { fieldName: -1 } (descending order). For a compound index, list multiple fields with their respective sort orders.
  • options: An optional document specifying index options, such as name, uniqueness, background builds, etc.

Examples

Creating a Single-Field Index

This example creates an index on the name field of the products collection in ascending order.

 db.products.createIndex( { name: 1 } ) 

Creating a Compound Index

This example creates a compound index on the category and price fields of the products collection.

 db.products.createIndex( { category: 1, price: -1 } ) 

Specifying Index Options

The options parameter of createIndex() allows you to customize the behavior of your index.

Common Options

  • name: Specifies a name for the index. If not specified, MongoDB generates a name. It's generally good practice to explicitly name your indexes.
  • unique: If true, creates a unique index. MongoDB will prevent inserting documents with duplicate values for the indexed fields.
  • background: If true, the index build process runs in the background, minimizing disruption to other operations. Recommended for large collections.
  • expireAfterSeconds: Creates a TTL (Time-To-Live) index. Documents will automatically be deleted after the specified number of seconds.

Examples

Creating a Unique Index

This example creates a unique index on the email field of the users collection.

 db.users.createIndex( { email: 1 }, { unique: true, name: "emailIndex" } ) 

Creating a Background Index

This example creates a background index on the createdAt field.

 db.logs.createIndex( { createdAt: 1 }, { background: true, name: "createdAtIndex" } ) 

Creating a TTL Index

This example creates a TTL index that removes documents from the events collection after 3600 seconds (1 hour).

 db.events.createIndex( { "lastActivityDate": 1 }, { expireAfterSeconds: 3600, name: "activityTTLIndex" } ) 

Important: For TTL indexes, the indexed field must be a Date type or an array containing Date type elements. If the field does not contain a date, the document will not expire.

Using the MongoDB Shell

All the examples shown above are executed within the MongoDB shell (mongosh). To use them, simply connect to your MongoDB instance using mongosh and then copy and paste the commands.

Verifying Indexes

You can use the getIndexes() method to view the indexes on a collection.

 db.collectionName.getIndexes() 

This will return an array of documents, each describing an index on the collection.

Dropping Indexes

You can use the dropIndex() or dropIndexes() method to remove indexes from a collection.

 // Drop a single index by name:
db.collectionName.dropIndex("indexName")

// Drop all indexes except the _id index:
db.collectionName.dropIndexes()