Blog

Indexing Types | MongoDB Indexing Tutorial

Compound Index | MongoDB Indexing Tutorial

Index Performance | MongoDB Indexing Tutorial

Indexing Types | MongoDB Indexing Tutorial

Unique Index | MongoDB Indexing Tutorial

List Indexes | MongoDB Indexing Tutorial

Create Index | MongoDB Indexing Tutorial

Key Takeaways

  • Indexes improve query performance by allowing quick lookups and avoiding full table scans.
  • MongoDB supports various index types including single field, compound, multikey, and others.
  • Indexes can increase database size and maintenance overhead.
  • Choose the right index type based on query patterns to optimize performance.

Preface: What is an index?

An index stores a portion of a collection's data in a sorted B-Tree, enabling faster queries. They improve performance by skipping full collection scans when executing queries.

While indexes enhance performance, they also increase database size as data is stored twice. Updating or deleting entries involves updating the index, which can add complexity.

Choosing the right index requires understanding your application's access patterns and identifying which fields are frequently queried.

Indexing Types in MongoDB

Consider a document structure like this:

{
  _id: ObjectID(...),
  email: "sam.erickson@gmail.com",
  name: "Sam Erickson",
  address: {city: "New York", state: "NY", zip: 10001},
  roles: ["admin", "user", "author", "originator"],
  age: 42,
  location: {
    type: "Point",
    coordinates: [-73.856077, 40.848447]
  },
  currLoc: [-73, 40],
  createdAt: ISODate("2016-11-29T00:53:02.000Z")
}

Single field index

A single field index targets a single field:

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

This index speeds up queries like:

db.collection.find({name: "Erica"})
db.collection.find({email: "ted@gmail.com", name: "Sam"})

You can index embedded documents similarly:

db.createIndex({"address"})
db.createIndex({"address.city"})

When to use a single field index

Opt for a single field index when queries frequently target a single field.

Compound index

Compound indexes involve multiple fields:

db.collection.createIndex({name:1, email:1, age:-1})

Speeds up queries like:

db.collection.find({name: "Erica"})
db.collection.find({name: "Ericoa", email: "ted@gmail.com", age: 30})

Effectiveness depends on order due to index prefixes.

When to use a compound index

Ideal for frequent multi-field queries.

Multikey index

Indexes each element in an array field:

db.collection.createIndex({roles:1})

Useful for fields like roles that contain arrays. MongoDB automatically creates this when you index an array field.

When to use a multikey index

Automatically created for array fields.

Text index

Facilitates text search queries:

db.collection.createIndex({name:"text"})

Limit to one text index per collection, but it can cover multiple fields:

db.collection.createIndex({name:"text",email:"text"})

When to use a text index

For legacy text-based searches and $text operator queries.

Wildcard index

Indexes dynamic fields that evolve over time:

db.collection.createIndex({"address.$**": 1})

Useful for changing data schemata, but can hit performance if overused.

When to use a wildcard index

Suitable for fields with evolving data shapes.

2dsphere index

Used for geospatial queries on an earth-like sphere:

document.collection.createIndex({location:"2dsphere"})

When to use a 2dsphere index

For geospatial queries involving GeoJSON objects.

2d index

Used for planar surface geospatial queries:

document.collection.createIndex({currLoc:"2d"})

When to use a 2d index

For geospatial queries on a 2D plane using legacy coordinate pairs.

Hashed index

Creates a hashed value for index field:

db.collection.createIndex({name:"hashed"})

When to use a hashed index

Ideal in sharded clusters for balancing data distribution.

Index Properties

Unique Indexes

Restricts a field to unique values:

db.collection.createIndex({email:1},{unique:true})

Prevents duplicate entries for an indexed field.

Partial Indexes

Indexes only part of a collection based on filters:

db.collection.createIndex(
   { email: 1, name: 1 },
   { partialFilterExpression: { age: { $gt: 30 } } }
)

Indexes documents with age greater than 30.

When to use a partial index

Useful for indexing a subset of data, saving storage and reducing performance costs.

Sparse Indexes

Excludes null/missing values:

db.collection.createIndex({age:1},{sparse:true})

Skips documents without the age field.

When to use a sparse index

For fields with many null/missing values to save space and improve performance.

TTL Indexes

Automatically deletes documents based on time constraints:

db.collection.createIndex({createdAt:1},{expireAfterSeconds:60000})

Removes records after 60,000 seconds.

When to use a TTL index

For expiring data like logs or session data with time constraints.

Hidden Indexes

Created for evaluation purposes without affecting operations:

db.collection.createIndex(
   { age: 1 },
   { hidden: true }
);

When to use a hidden index

To test the impact of dropping an index without operational interference.

FAQ

Why are indexes important in MongoDB?

Indexes significantly improve query performance by facilitating fast data searches and avoiding full collection scans.

Can you have multiple index types on the same collection?

Yes, MongoDB allows multiple index types within the same collection, each optimized for different query patterns.

How do indexes affect write performance?

Indexes can slow down writes, as any data modification requires updating the associated index to reflect the changes.

Mastering the tech interviewWhat everyone is doing wrong in tech interviews