A product catalog can have attributes that vary by product category. Shoes may have a size, batteries a capacity, and parcels a weight. Creating one ordinary index for every possible attribute can be impractical when the field names evolve. MongoDB wildcard indexes offer an index over varying paths within a selected document scope. This reference targets MongoDB 8.0 and uses controlled attributes objects. It explains how to scope the index, how a query still names an actual field path, and why one wildcard index is not a universal replacement for intentional compound indexes. The examples compare query membership rather than pretending a three-document fixture proves production performance.
Select the dynamic subtree deliberately
An index specification such as { 'attributes.$': 1 } covers supported values under the attributes subtree. The special token belongs in the index definition. A query still names a concrete path such as attributes.color or attributes.weight; it does not query an imaginary attributes.$ field. This is a path-oriented index, not a text search engine or a way to locate an arbitrary unknown key by value without supplying its path.
Keep stable identity fields, tenant IDs, and frequently sorted timestamps as explicit schema decisions. Put genuinely variable characteristics in a consistent subtree so their index scope is reviewable. A full-document wildcard may also index data that no workload needs, increasing write and storage overhead. The main fixture chooses the narrower attributes scope and leaves product names outside it. Schema flexibility remains a contract: storing numeric weight sometimes as a number and sometimes as a string will still give type-dependent comparison behavior. An index does not normalize inconsistent units or types.
Use wildcardProjection to control full-index scope
A full wildcard index can specify wildcardProjection to include or exclude eligible field paths according to its documented projection rules. The practice uses an inclusion projection for attributes, making the intended dynamic region explicit even though the index key is $**. Do not mix arbitrary inclusion and exclusion settings except for documented special cases. Index projection is also different from the projection that controls returned query fields.
A field omitted from the wildcard index still exists in its source document and can be returned to an authorized query. Excluding a private subtree from an index is therefore not an access-control mechanism. Set application authorization, collection privileges, or an appropriate public-data model independently. Index scope concerns query support and cost. Query projection concerns result shape. Security concerns who can read or change the underlying values. Keeping those three responsibilities distinct prevents an index-maintenance optimization from being mistaken for a privacy guarantee.
Review sparse behavior and multi-predicate limits
Wildcard indexes are sparse under their documented behavior: absent fields do not supply the corresponding indexed values. A query seeking documents where a path is missing may consequently need a different plan. Avoid forcing a sparse index for a query whose correct result includes documents it does not represent. The main fixture deliberately performs its missing-weight query without a hint and finds the product with no attributes.
A wildcard term can support a selected dynamic path, but several predicates on different dynamic paths are not equivalent to a purpose-built compound index over those fields. MongoDB has specific restrictions on how wildcard indexes serve such queries. Compound wildcard indexes available in this engine can combine ordinary fields with a wildcard term under documented rules, but they still do not make every arbitrary field combination free. Use workload evidence to promote common combinations to appropriate explicit indexes. Explain examined keys, document fetches, and remaining filters rather than concluding that an index name appearing in a plan means the whole query was covered.
Budget flexible indexing against real workloads
Each indexed value adds maintenance work when documents are inserted or changed. Deep and wide attribute structures can increase the number of index entries. Arrays introduce their own supported multikey behavior and limitations. A wildcard index also has restrictions involving index options and supported query shapes; it cannot be assumed to provide unique enforcement on every possible attribute path. If one dynamic key becomes a required business identity, model its uniqueness explicitly.
Record which concrete paths users actually query. If attributes.weight repeatedly appears with a tenant filter and a price sort, that repeatable workload deserves a specific index review. A wildcard index can help during exploration while an evolving schema stabilizes, but stable access patterns often benefit from deliberate ordinary indexes. The fixture names each wildcard index so inspection can confirm its scope. It avoids asserting exact explain stage names that can change between planner versions. Correct selected records and observed production execution statistics are stronger evidence than a tiny fixture's elapsed time or a general claim that flexible indexing improves all queries.
MongoDB documentation and version notes
MongoDB Wildcard Indexes Examples
Each example shows the code, the output it produces and what each part does.
Querying dynamic attributes with a wildcard index
The complete script resets a disposable catalog and creates a subtree wildcard index. Its concrete color query selects products one and three; its numeric weight range selects two and three. Product four lacks attributes altogether, so the missing-weight query returns it. The final sort stabilizes each printed ID list and is separate from wildcard index membership. No hint is applied to the missing-field query. This preserves the correct sparse-index result contract instead of attempting to prove that every predicate must use the same index.
const products = db.getSiblingDB('codevra_ref_wildcard').getCollection('products');
products.drop();
products.createIndex({ 'attributes.$**': 1 }, { name: 'dynamic_attributes' });
products.insertMany([
{ _id: 1, name: 'Light red', attributes: { color: 'red', weight: 4 } },
{ _id: 2, name: 'Heavy blue', attributes: { color: 'blue', weight: 8 } },
{ _id: 3, name: 'Heavy red', attributes: { color: 'red', weight: 10 } },
{ _id: 4, name: 'Unspecified' }
]);
function ids(query) { return products.find(query).sort({ _id: 1 }).toArray().map(d => d._id).join(','); }
print('red: ' + ids({ 'attributes.color': 'red' }));
print('weight at least eight: ' + ids({ 'attributes.weight': { $gte: 8 } }));
print('missing weight: ' + ids({ 'attributes.weight': { $exists: false } }));red: 1,3
weight at least eight: 2,3
missing weight: 4MongoDB Wildcard Indexes in Real Projects
Scope a wildcard index with wildcardProjection
Create a full wildcard index restricted to the attributes subtree with an inclusion wildcardProjection, then query a nested dynamic shipping zone. The solution also returns the ordinary product name in its result projection. That name is readable even though the index scope focuses on attributes. Inspecting the index's projection confirms the maintenance configuration, while the query result confirms membership. The third product contains private data but no shipping zone; its omission comes from the predicate, not from an authorization boundary created by the index. Treat this example as a comparison of index scope and result scope.
const products = db.getSiblingDB('codevra_ref_wildcard').getCollection('practice');
products.drop();
products.createIndex({ '$**': 1 }, { name: 'attributes_projection', wildcardProjection: { attributes: 1 } });
products.insertMany([
{ _id: 1, name: 'West parcel', attributes: { shipping: { zone: 'west' } }, private: { note: 'internal' } },
{ _id: 2, name: 'East parcel', attributes: { shipping: { zone: 'east' } } },
{ _id: 3, name: 'No zone', private: { note: 'internal' } }
]);
const index = products.getIndexes().find(i => i.name === 'attributes_projection');
print('indexed subtree: ' + Object.keys(index.wildcardProjection).join(','));
const matches = products.find({ 'attributes.shipping.zone': 'west' }, { _id: 0, name: 1 }).toArray();
print('matching name: ' + matches[0].name);indexed subtree: attributes
matching name: West parcelMongoDB Wildcard Indexes FAQ
Should queries use the $** token?
The index specification uses it to describe varying paths. The actual query supplies the concrete field path being tested, such as attributes.color. A wildcard index does not infer which unknown key the user intended. Keep path selection controlled and validated at the application boundary, particularly when users choose filters through a catalog interface.
Does wildcardProjection hide private fields from readers?
No. It limits which supported fields the index represents, not which fields an authorized operation can retrieve from the source document. Use query projection for result shaping and authorization for access decisions. A collection document omitted from index scope remains a document. Treating indexing scope as security would leave the original data readable through ordinary collection queries.
Why avoid a hint for the missing-weight query?
The sparse index does not represent every absent path in the same way as a complete ordinary document scan. Forcing an unsuitable index can sacrifice result completeness or fail under the documented planner rules. The fixture lets the engine choose a valid plan and checks the correct missing-field membership. Review sparse behavior before forcing plans for absence or null-related predicates.
Can one wildcard index optimize every pair of attributes?
No. Multiple dynamic predicates have documented index-use restrictions, and a chosen wildcard path is not a general compound key for all other paths. Observe common workloads and build explicit indexes when a recurring combination merits them. Flexible path coverage is useful, but it does not remove the need to inspect remaining filters, sorts, and fetched documents.
MongoDB Wildcard Indexes Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which main-fixture product matches missing attributes.weight?
MongoDB Wildcard Indexes Quiz
2 questions to check what you learned.
Which query path matches the red products under the subtree index?
- attributes.color
- attributes.$**
- name.color
Why does the practice return a name that is outside the indexed attributes subtree?
- The query may fetch the source document and project its name
- wildcardProjection grants universal read access to omitted fields
- The index copies every unindexed field into attributes automatically