Browse documentation
MongoDB TutorialVerified with mongodb 7.5.0

MongoDB Index Examples and Explain Plans

Create MongoDB indexes for real query examples, choose compound key order, read execution statistics, and verify access paths with explain plans.

Why indexes matter

Without a useful index, MongoDB may inspect every document in a collection to answer a query. An index stores selected field values in an ordered structure so the server can narrow the search. Indexes improve supported reads but consume storage and add work to writes.

Build indexes from real access patterns, not from every field that might someday be queried.

Prepare a query shape

Suppose an application lists recent paid orders for one customer:

use("mongog_tutorial");
const orders = db.collection("indexed_orders");

orders.find({
  customerId: "customer-42",
  status: "paid",
}).sort({ placedAt: -1 }).limit(20);

A compound index can support the equality filters followed by the sort:

orders.createIndex(
  { customerId: 1, status: 1, placedAt: -1 },
  { name: "customer_status_recent" },
);

Compound index order matters. A common starting rule is equality fields first, then sort fields, then range fields, but the final choice should be verified with your workload and explain output.

Read an explain plan

Call explain() on the cursor to see how MongoDB planned and executed a query:

orders.find({
  customerId: "customer-42",
  status: "paid",
}).sort({ placedAt: -1 }).limit(20).explain("executionStats");

Look for these signals:

  • IXSCAN indicates an index scan; COLLSCAN indicates a collection scan.
  • totalKeysExamined counts index entries inspected.
  • totalDocsExamined counts documents fetched and tested.
  • nReturned is the number of documents produced.
  • A separate blocking sort stage can indicate that the chosen index did not provide the requested order.

Small tutorial collections may be scanned even when an index exists because a scan is cheap. Evaluate realistic data volume before drawing performance conclusions.

Unique and partial indexes

A unique index protects a business identity:

orders.createIndex(
  { externalOrderId: 1 },
  { unique: true, name: "unique_external_order" },
);

Existing duplicate values must be resolved before this index can be built. A partial index stores only documents matching a filter and is useful when only a subset participates in a rule:

orders.createIndex(
  { customerId: 1, placedAt: -1 },
  {
    name: "recent_open_orders",
    partialFilterExpression: { status: "open" },
  },
);

Queries must be compatible with the partial filter for the server to use that index safely.

Use the MongoG administration view

MongoG can list and manage indexes from its administration workspace. The query editor remains useful for reproducible index scripts and detailed explain() experiments. Index creation is a write operation and should be reviewed like a schema change.

Expected result

After representative data exists, the customer/status query can use customer_status_recent to filter and return records in requested order. Explain statistics provide evidence instead of relying on an index name alone.

Understand index prefixes and covered queries

A compound index can support queries that use its leading prefix. The index { customerId: 1, status: 1, placedAt: -1 } can efficiently narrow by customerId, and often by customerId plus status. A query only on placedAt cannot generally use the earlier keys as though they were absent.

A covered query can answer from index keys without fetching full documents when the filter and returned fields are available from the index. For example, a carefully projected query may reduce document reads:

orders.find(
  { customerId: "customer-42", status: "paid" },
  {
    projection: {
      _id: 0,
      customerId: 1,
      status: 1,
      placedAt: 1,
    },
  },
).sort({ placedAt: -1 });

Do not widen an index with every projected field automatically. Larger indexes consume more memory and increase write cost; coverage must be worth it for the workload.

Compare before and after safely

Use a tutorial-only collection with enough representative data, capture executionStats, create the candidate index, and capture the same query again. Compare:

  • documents and keys examined per returned document;
  • whether a blocking sort remains;
  • execution time across repeated runs rather than one cold measurement;
  • index size and write impact;
  • performance for other important query shapes.

Plan selection can change as collection size and value distribution change. Production monitoring matters even after a staging explain looks good.

Know specialized index choices

Multikey indexes support array fields, TTL indexes expire eligible date-based records, text indexes provide MongoDB’s built-in text search behavior, and wildcard indexes cover dynamic field paths. Each has constraints; do not choose a specialized index from its name alone.

Practice by creating two candidate compound indexes with different key orders for the same tutorial query. Run executionStats, compare examined counts and sort stages, then drop only the inferior tutorial index. Keep the winning index only if its write and storage cost is justified.

Common mistakes

  • Adding many overlapping indexes increases write latency and memory pressure.
  • Looking only for IXSCAN ignores how many keys and documents were examined.
  • Testing with a nearly empty collection can produce a plan that differs from production.
  • Creating a unique index without checking existing duplicates causes the build to fail.
  • Assuming any subset of compound index fields is equally usable ignores the leading-prefix rule.
  • Optimizing one read without measuring write cost and index memory can move the bottleneck rather than remove it.
  • Treating one explain execution time as a benchmark ignores cache state and normal workload variation.

Continue learning

Apply the same measurement to date-range queries, array queries, and aggregation pipelines. Use these access paths inside MongoDB transactions, or inspect them through MongoG administration tools. See the official index guide and Node.js driver indexes documentation.