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.
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 })
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 })
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 })
Example query:
{
"name": "Laptop",
"tags": ["electronics", "computing", "portable"]
}
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 } }
)
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 } } }
)
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 } )
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 }
)
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
}
)
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 } )
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 })
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" }
}
)
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)