Four index types handle values that are not a single scalar. An index becomes multikey the moment it meets an array, storing one key per element; you never ask for that.
db.orders.createIndex({ 'items.sku': 1 });
const e = db.orders.find({ 'items.sku': 'SKU-3799' }).explain('executionStats');
print(JSON.stringify(e.queryPlanner.winningPlan.inputStage.multiKeyPaths) +
' keys=' + e.executionStats.totalKeysExamined);
db.orders.createIndex({ tags: 1, 'items.sku': 1 }); // two arrays in one index{"items.sku":["items"]} keys=52
MongoServerError: ... cannot index parallel arrays [items] [tags]multiKeyPaths names which prefix of the path is the array. The cost is key count: items.sku_1 holds 2.5 keys per document and 2,498,560 bytes, four times the 634,880 of the scalar customerId_1. One index may traverse at most one array field; the key count would otherwise be the product of the lengths.
A text index tokenizes strings, stems them and drops stop words; a collection may have only one, spanning many fields with weights. Under createIndex({ title: 'text', body: 'text' }, { weights: { title: 5 } }), a $text search for index also matches "Indexing" through stemming, and a title hit outranks a body hit five to one when you sort by { $meta: 'textScore' }. Text indexes suit a help center and fail at product search: no fuzzy matching, no synonyms, no tuning beyond weights. Atlas Search covers MongoDB 1,815 Search.
A 2dsphere index stores coordinates as geohash cells on an Earth-shaped sphere, so proximity queries become range scans. Values must be GeoJSON, [longitude, latitude] in that order; $geoNear as a pipeline's first stage and $near inside find both return documents nearest first, the former with a computed distance.
A wildcard index covers every field under a path, including ones that did not exist when you created it — the tool for per-tenant custom attributes, a bad habit elsewhere. After db.events.createIndex({ 'attrs.$**': 1 }), a query on attrs.size explains to the key pattern {"$_path":1,"attrs.size":1}: that synthetic field is how one B+ tree holds every field, so the query scans only its slice. Hence the restrictions — never unique, TTL, hashed, text, geospatial or a shard key, one wildcard term per compound index, one predicate field per query, and a covered query only when that lone field is all you project.