Index Types
Different index types match different query shapes. Picking the wrong one wastes disk and RAM without speeding up your app.
Choosing the right index type
Different index types match different query shapes. Picking the wrong one wastes disk and RAM without speeding up your app.
Real-life example: Index types are different catalog systems — alphabetical by author, by ISBN, or full-text search in the back of the library.
- Single-field — one key path
- Compound — multiple fields in one B-tree
- Multikey — automatic when indexing array fields
- Text — word search on string fields
- Unique, TTL, partial — constraints and special behaviour
Single-field and compound indexes
Single-field indexes support equality and range on one path — email, createdAt, status.
Compound indexes cover queries on prefixes of the key list — { a: 1, b: 1, c: 1 } helps { a }, { a, b }, and { a, b, c } but not { b } alone.
ESR rule for compound indexes: Equality fields first, Sort fields second, Range fields last.
Real-life example: Compound index { city: 1, grade: 1, name: 1 } is a phone book sorted by city, then grade, then name — you must know the city to use the grade ordering efficiently.
// Query: city = X, grade in [10,11], name >= "K"
db.students.find({
"address.city": "Delhi",
grade: { $in: [10, 11] },
name: { $gte: "K" }
}).sort({ name: 1 })
// Index following ESR: Equality (city, grade via in), Sort (name), Range on name
db.students.createIndex({
"address.city": 1,
grade: 1,
name: 1
})Multikey indexes
When you index an array field, MongoDB builds a multikey index — one index entry per array element.
A compound index can include at most one array field. Queries on tags or categories often hit multikey indexes automatically.
Real-life example: Indexing subjects on student documents creates one index entry per subject — finding all Math students uses the index.
db.products.createIndex({ tags: 1 })
// Uses multikey index
db.products.find({ tags: "wireless" })
// $all on multiple tags — index still helps first tag
db.products.find({ tags: { $all: ["wireless", "sale"] } })Text indexes
Text indexes tokenize words for $text search — one text index per collection (can include multiple string fields with weights).
For advanced fuzzy search and autocomplete, Atlas Search is the modern choice; text indexes remain useful for simple search boxes.
Real-life example: Text index on title and body is a magazine index — search 'MongoDB aggregation' and get relevant articles ranked by score.
db.articles.createIndex(
{ title: "text", body: "text" },
{ weights: { title: 10, body: 1 }, name: "article_text" }
)
db.articles.find(
{ $text: { $search: "aggregation pipeline tutorial" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })Unique, TTL, and partial indexes (brief)
Unique indexes enforce distinct values — emails, SKUs, slugs. Duplicate inserts fail with E11000.
TTL indexes delete documents when a date field ages out — sessions, OTP codes, log rows.
Partial indexes only index documents matching a filter — smaller index when only active users need speed.
Real-life example: TTL on session.expiresAt is automatic cleanup — like a library that returns overdue books to the shelf without a librarian.
// Unique slug for Rishtaara blog posts
db.posts.createIndex({ slug: 1 }, { unique: true })
// Sessions expire after 24 hours
db.sessions.createIndex(
{ lastActivity: 1 },
{ expireAfterSeconds: 86400 }
)
// Index only active products — saves space
db.products.createIndex(
{ category: 1, price: 1 },
{ partialFilterExpression: { active: true } }
)