MongoDB Multikey Index Limits

Understand compound multikey restrictions, same-element bounds with elemMatch, and why a unique array index constrains documents rather than repeated elements.

Lesson 40 of 43Intermediate10 min read

An index on a scalar value usually has a straightforward relationship to its document. An indexed array can generate several keys for the same document, so MongoDB treats it as multikey. That changes what compound indexes can represent and what predicates mean. This MongoDB 8.0 reference builds on basic arrays and indexes with two controlled experiments. The main fixture shows a compound index accepting one array field and rejecting a document with independent arrays in both indexed fields. The practice separates range predicates that different array elements can satisfy from a same-element requirement. It also demonstrates that a unique array index does not reject duplicate values within one document.

Model the compound array restriction correctly

Consider an index on tags and region. A document with tags as an array and region as a scalar can contribute keys for its tag values paired with that region. If both fields are independent arrays in one document, the compound index would need an unsupported parallel-array expansion. The main fixture catches that rejected write and prints its documented error code under MongoDB 8.0.

The restriction is evaluated for each indexed document. Different documents may place their one array in different indexed fields, provided no indexed document requires both independent arrays at once. Existing valid data therefore does not guarantee that a later schema change remains index-compatible. Validate the document shape at the application or database boundary before new fields become arrays. Do not respond to a failed write by removing a useful index without reviewing the query and schema requirements. A separate relationship collection or a differently structured array of embedded objects may fit the intended association more accurately.

Separate independent matches from one-element matches

The practice inserts scores [70, 100] for one student and [92] for another. The predicate scores: { $gte: 90, $lte: 95 } can match the first student's array: one element satisfies the lower comparison, while another satisfies the upper comparison. Neither seventy nor one hundred lies within the interval. That behavior is legal because the predicate does not require both comparisons to apply to one element.

Use $elemMatch when the question is whether one array element lies inside the interval. Then only the student with ninety-two matches. This is a correctness requirement before it is an optimization. Adding an index does not change the business meaning of the query. The same-element predicate also allows documented intersection of multikey bounds for this scalar-array case. Without it, the engine cannot assume the interval intersection represents all legal matches. Read the query semantics and the explain bounds together rather than treating a narrower scan as the reason to change result meaning.

Interpret unique multikey indexes across documents

A unique index on labels prevents another document from claiming an indexed key already claimed by a different document. Repeating blue twice inside the first document does not create a uniqueness violation against that same document. In the practice, the array ['blue', 'blue'] inserts successfully, while a second document containing blue fails with duplicate-key code 11000.

If the application requires no duplicate elements inside one array, enforce that separate invariant through an appropriate validation or update strategy. $addToSet can prevent adding another equal element in its update operation, but it does not automatically repair all previously duplicated values. A unique multikey index is not an array-normalization command. Think about what uniqueness represents: globally reserved labels across owners differ from a deduplicated set of labels within each owner. The fixture intentionally creates the first policy so the distinction is visible. Different applications often need the second policy instead.

Review bounds, coverage, and future mutations

Multikey explain plans can show several examined keys for one returned document. Repeated document references need not mean duplicate result documents. Returning an entire array may require fetching the source document because index keys do not reconstruct every original array property. Covered-query rules are consequently more restrictive, and $elemMatch has documented coverage limitations. Avoid promising an index-only query merely because its scalar counterpart would be covered.

Array sort behavior and index-supported sorting also require their own review. A compound multikey index that helps filtering may still require an in-memory sort for a particular predicate and order. Hashed indexes cannot be multikey, and a multikey index cannot serve as a shard-key index under its documented restrictions. For a proposed migration, test representative inserted and updated shapes as well as read queries. The main fixture prints the surviving document count after the failed insertion so the write boundary is explicit. Its catch block reports the expected error rather than silently pretending both records were stored.

MongoDB documentation and version notes

MongoDB Multikey Index Limits Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Rejecting a compound index on two arrays

Run this complete mongosh script in its dedicated fixture database. Dropping the disposable collection resets both its records and indexes. The first document has array tags and scalar region, so the compound index is valid. The attempted second document has both fields as independent arrays and fails. The catch prints the MongoDB 8.0 error code, and countDocuments confirms that the rejected write did not add a record. This experiment does not imply that all dotted fields sharing one embedded array are forbidden; shared-array structures have their own documented multikey bounds rules.

MongoDB Shell
const records = db.getSiblingDB('codevra_ref_multikey').getCollection('records');
records.drop();
records.createIndex({ tags: 1, region: 1 });
records.insertOne({ _id: 1, tags: ['red', 'blue'], region: 'west' });
try {
  records.insertOne({ _id: 2, tags: ['green'], region: ['east', 'west'] });
  throw new Error('Parallel-array insertion unexpectedly succeeded');
} catch (error) {
  if (error.code !== 171) throw error;
  print('parallel-array code: ' + error.code);
}
print('stored documents: ' + records.countDocuments({}));
Output
parallel-array code: 171
stored documents: 1

MongoDB Multikey Index Limits in Real Projects

Compare array range matching and unique index writes

Predict both range-query results and the unique-index write outcome before running the solution. The independent comparisons match IDs one and two, whereas elemMatch matches only ID two. A separate collection makes the uniqueness demonstration independent of the score index. The code checks the precise expected duplicate-key error and rethrows unexpected failures. It prints the first record's unchanged two-element array, confirming that indexing did not deduplicate the stored document. These experiments isolate result semantics and enforcement; a realistic performance evaluation would additionally inspect execution statistics on representative data volume.

MongoDB Shell
const demo = db.getSiblingDB('codevra_ref_multikey');
const scores = demo.getCollection('scores'); scores.drop();
scores.createIndex({ scores: 1 });
scores.insertMany([{ _id: 1, scores: [70, 100] }, { _id: 2, scores: [92] }]);
const independent = scores.find({ scores: { $gte: 90, $lte: 95 } }).sort({ _id: 1 }).toArray();
const sameElement = scores.find({ scores: { $elemMatch: { $gte: 90, $lte: 95 } } }).sort({ _id: 1 }).toArray();
print('independent: ' + independent.map(d => d._id).join(','));
print('same element: ' + sameElement.map(d => d._id).join(','));
const labels = demo.getCollection('labels'); labels.drop();
labels.createIndex({ labels: 1 }, { unique: true });
labels.insertOne({ _id: 1, labels: ['blue', 'blue'] });
try { labels.insertOne({ _id: 2, labels: ['blue'] }); }
catch (error) { if (error.code !== 11000) throw error; print('cross-document code: ' + error.code); }
print('stored array length: ' + labels.findOne({ _id: 1 }).labels.length);
Output
independent: 1,2
same element: 2
cross-document code: 11000
stored array length: 2

MongoDB Multikey Index Limits FAQ

Does a unique index remove duplicate array elements?

No. It constrains indexed keys across different documents and does not rewrite the source array. The practice retains both blue elements in document one while rejecting a second document that claims blue. Use a separate document invariant or a suitable set-oriented update when duplicates inside one array are unwanted. Index uniqueness and array normalization answer different questions.

Why can seventy and one hundred satisfy the range query?

The independent array comparisons can be satisfied by different elements. One hundred is at least ninety, and seventy is at most ninety-five. Neither element itself is in the interval, but the document still meets those independent conditions. Require elemMatch when one element must satisfy both. This prevents a business-logic mistake even if no index exists.

Are two dotted fields from one embedded array always parallel arrays?

No. Fields sharing an embedded array path differ from two independent array fields. MongoDB documents conditions for combining bounds from that shared structure, including elemMatch at the correct common path. Inspect the actual schema and path relationship. Do not apply the simple tags-and-region failure example as a blanket prohibition against indexing multiple fields of one array of embedded objects.

Can I infer covered queries from scalar examples?

Only after checking the multikey coverage rules and the actual explain plan. Returning an array or using elemMatch can prevent coverage even when the requested scalar fields appear in an index. The engine may need the original document to validate or reconstruct the result. Examined-key and fetched-document counts provide evidence that a small syntax comparison cannot supply.

MongoDB Multikey Index Limits Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

Which student has one score between ninety and ninety-five inclusive?

MongoDB Multikey Index Limits Quiz

2 questions to check what you learned.

  1. Which new document violates the main compound index restriction?

    • One with independent arrays in both tags and region
    • One with two strings in tags and a scalar region
    • One with scalar values in both tags and region
  2. Why does the unique labels index accept blue twice in document one?

    • Repeated keys within one document do not violate cross-document uniqueness
    • Unique indexes ignore all array values
    • The index deletes the second blue before storing the document