DEV Community

Cover image for MongoDB Indexes: The Superpower to Speed Up Your Queries ⚡
Anh Tu Nguyen
Anh Tu Nguyen

Posted on

MongoDB Indexes: The Superpower to Speed Up Your Queries ⚡

Imagine walking into a massive library to find a single book. Without an index or catalog, you’d have to go shelf by shelf, scanning every title—sounds exhausting, right? MongoDB indexes are like a magical catalog that speeds up your searches, so MongoDB can find what it needs in a flash.

Index

Just like library catalogs, indexes make data retrieval way faster. MongoDB uses a clever little structure called a B-tree to keep everything organized. B-trees allow MongoDB to skip over data that’s irrelevant to your search.

Want to know more about B-trees? Check out this awesome blog on B-trees.


Types of MongoDB Indexes

MongoDB offers several types of indexes, each with its own quirks and superpowers. Let’s take a look! 🚀

Single Field Index

This is your classic, no-frills index, created on a single field. If you have a collection of users and often query by username, creating a single field index on username helps MongoDB find username quickly instead of skimming through every document.

db.users.createIndex({ username: 1 })

Enter fullscreen mode Exit fullscreen mode

Here:

  • username is the field we’re indexing.
  • 1 means ascending order (you could also use -1 for descending order).

Compound Indexes

Need to search by multiple fields? A compound index includes more than one field, making multi-field searches lightning fast! Imagine a shopping app where you often query category and price. A compound index lets MongoDB efficiently find items in that category and price range.

db.products.createIndex({ category: 1, price: -1 })
Enter fullscreen mode Exit fullscreen mode

MongoDB can use this index to search by both category and price, or just category (since it’s the first field in the index). However, searches only on price won’t use this index.

Tip: If you have both a compound index { a: 1, b: 1 } and a single index { a: 1 }, consider removing the single index. MongoDB will happily use the compound index for both!

Multikey Indexes

Multikey indexes are MongoDB’s answer for indexing arrays. If you have a tags field storing an array (like ["electronics", "computing", "portable"]), creating a multikey index lets MongoDB search each element as if it were a standalone field.

db.products.createIndex({ tags: 1 })
Enter fullscreen mode Exit fullscreen mode

Example query:

{
  "name": "Laptop",
  "tags": ["electronics", "computing", "portable"]
}
Enter fullscreen mode Exit fullscreen mode

MongoDB uses the multikey index to find all products tagged with computing without digging through each tag manually.

Note: Compound indexes can have only one array field. Also, multikey indexes can get hefty for large arrays, so be mindful.

Index Properties

Index properties affect how the query planner uses an index and how indexed documents are stored. You can specify index properties as optional parameters when you create an index.

Case-Insensitive Indexes

Need case-insensitive searches? Use collation options when creating indexes.

db.fruit.createIndex(
   { type: 1 },
   { collation: { locale: 'en', strength: 2 } }
)
Enter fullscreen mode Exit fullscreen mode

This will allow you to find all variations of apple (like Apple or APPLE). Just remember that your queries also need to specify the same collation.

Partial Indexes

Want an index that only includes specific documents? A partial index lets you add a filter, so only documents that meet the condition are indexed.

db.restaurants.createIndex(
   { cuisine: 1 },
   { partialFilterExpression: { rating: { $gt: 5 } } }
)
Enter fullscreen mode Exit fullscreen mode

Only restaurants with a rating greater than 5 will be indexed—less storage, more efficiency!

Sparse Indexes

A sparse index skips any documents that don’t have the indexed field, unlike other indexes which include every document, even if the field is missing or null.

db.scores.createIndex( { score: 1 } , { sparse: true } )
Enter fullscreen mode Exit fullscreen mode

This helps MongoDB return only documents that actually have a score field when you query based on that field.

TTL Indexes

TTL indexes automatically remove documents after a set time. Great for logs, session data, or anything that only needs to live temporarily.

The TTL index expireAfterSeconds value must be within 0 and 2147483647 inclusive.

Here, documents expire after 1 hour (3600 seconds) from their lastModifiedDate:

db.eventlog.createIndex(
   { lastModifiedDate: 1 },
   { expireAfterSeconds: 3600 }
)
Enter fullscreen mode Exit fullscreen mode

You can create a TTL index with a Partial Index to expire documents with specific filter expressions.

db.eventlog.createIndex(
   { "lastModifiedDate": 1 },
   {
      name: "Partial-TTL-Index",
      partialFilterExpression: { canDelete : true },
      expireAfterSeconds: 10
   }
)
Enter fullscreen mode Exit fullscreen mode

Unique Indexes

A unique index ensures no duplicate values for the indexed field. MongoDB automatically makes the _id field unique, but you can add unique constraints to other fields, too.

db.members.createIndex( { "user_id": 1 }, { unique: true } )
Enter fullscreen mode Exit fullscreen mode

Need a unique constraint on a combination of fields? No problem! With compound unique indexes, MongoDB enforces uniqueness across the combination of the index key values, so only a unique pair of values for each indexed field can exist.

db.users.createIndex({ firstName: 1, lastName: 1 }, { unique: true })
Enter fullscreen mode Exit fullscreen mode

Sometimes, you don’t want a unique constraint across your whole collection—just a specific subset of documents. With partialFilterExpression, you can apply a unique constraint only to documents that match certain criteria, while the rest of the documents ignore it.

db.events.createIndex(
   { userId: 1, status: 1 },
   {
      unique: true,
      partialFilterExpression: { status: "active" }
   }
)
Enter fullscreen mode Exit fullscreen mode

Note: The unique constraint only applies to documents that match the filter expression. MongoDB won’t prevent you from inserting documents that don’t meet the unique constraint if they don’t satisfy the filter criteria.

Wrap-Up 🎉

Indexes are your friends! They make MongoDB queries way faster, helping you find exactly what you need without MongoDB combing through the entire collection. Whether you’re indexing single fields, arrays, or setting up TTL for auto-cleanup, each index type has its own special trick to speed things up. Just remember, indexes do require some storage, so don’t go overboard.

Happy querying, and may the MongoDB index force be with you! 🖖

Top comments (0)