-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Query Execution
-
None
-
None
-
None
-
None
-
None
-
None
-
None
SBE $lookup can use a partial index on the foreign collection via the Dynamic Indexed Loop Join (DILJ) strategy, deciding per local document whether the partial index covers its key(s) and otherwise falling back to a collection scan. This is sound only because the partial filter is constrained to reference nothing but the foreign field, so P(foreignDoc) == P(localKey). Two conservative restrictions currently force eligible queries to fall back when they could use the index; lifting either is a performance improvement, not a correctness fix.
First, the planner rejects a partial index when the foreign field is a dotted path (e.g. "b.b1"). This is because the runtime check materializes the single local key into a slot registered at the top-level foreign field and reads it at path.getPart(0); a dotted field would need a synthetic nested object built per key, or a generateFilter path that binds a value to a dotted path.
Second, a local document producing more than one key (an array-valued local field, e.g. {{{}
{a: [3, 10]}{}}}) always takes the collection-scan fallback, even when the index would be sound. Correctness for a multi-key document needs a forall — every key must satisfy the partial filter, or the index would drop matches for the uncovered keys — and the natural way to express that is inside a traverseF lambda. But generateFilter requires its input in a materialized slot while a lambda only provides a per-element value, so the filter can't run inside the forall. The current version sidesteps this by restricting to single-key documents. Lifting it means adding a value-input path to generateFilter, or dispatching simple filters to the existing value-form helpers (generateComparisonExpr / generateInExpr).
- is related to
-
SERVER-116515 Use partial indexes in SBE $lookup
-
- Closed
-