Schema Design and Index Design Must Work Together
Data shape determines query and index shape
Schema design and indexing are not separate phases. The location of a field—top-level, nested, inside an array, or in a referenced collection—changes how the application queries it and which index can support that query.
Embedded field index
For documents shaped like:
{
_id: ObjectId("65a000000000000000000080"),
customerId: ObjectId("65a000000000000000000010"),
address: {
country: "IN",
postalCode: "560001"
}
}
an index can target the nested field:
db.customers.createIndex({ "address.postalCode": 1 });
Array index and multikey behavior
If tags is an array, an index on tags becomes a multikey index:
db.products.createIndex({ tags: 1 });
db.products.find({ tags: "mongodb" });
Array indexing has restrictions, especially when indexing multiple array fields in the same compound index for one document. Understand multikey index behavior before modeling a query that depends on multiple arrays.
Compound indexes should follow real queries
Suppose the application frequently retrieves a customer's orders by status, newest first:
db.orders.find({
customerId,
status: "shipped"
}).sort({ createdAt: -1 });
A candidate index is:
db.orders.createIndex({
customerId: 1,
status: 1,
createdAt: -1
});
The best order depends on the query shapes, selectivity, sort requirements, and other operations. Test with explain("executionStats") and representative data.
Referenced child collections
If comments are separate from posts, a post's document shape cannot by itself provide an efficient paginated comment list. The comments collection needs an index designed for the query, such as { postId: 1, createdAt: -1, _id: -1 }.
Projection and data locality
Embedding may reduce the need for an extra read, but a very large embedded document can make fetching a small subset of fields less efficient than a purpose-built collection. Evaluate actual document size, projection, working set, index size, and network payload.
- Multikey index:
An index that indexes values from an array field. - Compound index:
An index containing multiple fields in a defined order. - Execution statistics:
Explain output that helps compare examined keys/documents with returned results.
A schema decision should be reviewed alongside the queries and indexes it enables. A model is not complete until its expected read and write paths have been tested.
db.orders.createIndex({
customerId: 1,
status: 1,
createdAt: -1
});
db.orders.find({
customerId: ObjectId("65a000000000000000000010"),
status: "shipped"
})
.sort({ createdAt: -1 })
.limit(20)
.explain("executionStats");- Index nested and array fields according to actual query patterns.
- Review schema and index design together.
- Use realistic explain plans rather than assuming a proposed index will be effective.
Why should the comments collection have its own index when comments are modeled separately?