Multikey Indexes
When you index a field whose value is an array, MongoDB automatically builds what's called a multikey index — one index entry per array element rather than one entry per document. No special syntax is required; MongoDB detects the array shape at index-build time.
How Array Values Get Indexed
One document, multiple index entries
db.posts.createIndex({ tags: 1 })
db.posts.insertOne({ _id: 1, title: "Intro to MongoDB", tags: ["mongodb", "nosql", "database"] })
// Creates THREE separate index entries:
// "mongodb" → _id: 1
// "nosql" → _id: 1
// "database" → _id: 1
// All three entries point back to the SAME document.A single-element match is enough
db.posts.find({ tags: "nosql" }) // matches the document above — one array element is enoughtags.Checking isMultikey in explain()
isMultiKey in the explain output
db.posts.find({ tags: "nosql" }).explain(){
queryPlanner: {
winningPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
indexName: 'tags_1',
isMultiKey: true, // confirms this index indexes an array field
multiKeyPaths: { tags: ['tags'] }
}
}
}
}isMultiKey: true plus multiKeyPaths tells you exactly which field(s) in the index are the array-valued ones — useful when a compound index mixes scalar and array fields and you're not sure which part triggered multikey behavior.The Big Limitation: One Array Field Per Compound Index
A compound index can include at most one array-valued field. Trying to create a compound index on two array fields at once fails outright — MongoDB has no way to represent the cross-product of two independently-varying arrays as a single flat B-tree efficiently.
This fails — two array fields in one compound index
db.posts.createIndex({ tags: 1, categories: 1 })
// If BOTH "tags" and "categories" are arrays on the same documents:
// Error: cannot index parallel arrays [categories] [tags]This works — one array field, one scalar field
db.posts.createIndex({ tags: 1, publishedAt: -1 }) // tags is an array, publishedAt is a scalar — fine$elemMatch Queries with a Multikey Index
When the array holds embedded documents and you filter on multiple sub-fields together, $elemMatch combined with a compound multikey index can still be served efficiently — as long as the index covers the fields inside the array being matched.
Indexing fields inside an array of sub-documents
db.orders.createIndex({ "items.sku": 1, "items.qty": 1 })
db.orders.find({
items: { $elemMatch: { sku: "WIDGET-42", qty: { $gte: 2 } } }
})
// Can use the compound index on items.sku / items.qty when both
// conditions apply to the SAME array element, matching $elemMatch semantics.items.sku and items.qty above) is not the "two array fields" restriction — that restriction is about two different, independently-varying top-level arrays, not two fields nested inside the same array of embedded documents.Bounds and Performance
Because a multikey index has one entry per array element, a query that matches many elements across many documents can examine far more index keys than the number of documents actually returned — watch totalKeysExamined vs nReturned in explain() just like any other index.
Checking multikey index efficiency
db.posts.find({ tags: { $in: ["mongodb", "nosql", "database"] } }).explain("executionStats")
// $in against a multikey index scans keys for EACH value in the $in list —
// totalKeysExamined can be notably higher than a simple equality lookupIndexing an array field is automatic — MongoDB detects the array and builds a multikey index with one entry per element.
A single array value matching is enough to satisfy an equality filter against a multikey-indexed field.
A compound index can include at most one array-valued field per document — "parallel arrays" on the same document will error.
isMultiKey: trueandmultiKeyPathsinexplain()confirm which fields triggered multikey behavior.Use
$elemMatchwith a compound index over multiple sub-document fields to correctly match conditions against the SAME array element.