The query planner does not trim bounds-generating inequality predicates from the expression tree, when the value being compared to is one of the following BSON types:
- Object
- Undefined
- RegEx
- DBRef
- Code
- Symbol
- CodeWScope
As a result, such predicates are not eligible for covering behavior, and require an unnecessary additional match operation after the document is fetched from disk.
Reproduce as follows:
> db.foo.drop() true > db.foo.ensureIndex({a:1}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.foo.find({a:{$gte:function(){ return 0; }}}).explain('queryPlanner').queryPlanner.winningPlan { "stage" : "FETCH", // Unexpected: FETCH does not need a filter with $gte predicate here. "filter" : { "a" : { "$gte" : function (){ return 0; } } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "a" : 1 }, "indexName" : "a_1", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "a" : [ "[function (){ return 0; }, CodeWScope( , {}))" ] } } } > db.foo.find({a:{$eq:function(){ return 0; }}}).explain('queryPlanner').queryPlanner.winningPlan { "stage" : "FETCH", // Expected: No filter with $eq predicate here. "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "a" : 1 }, "indexName" : "a_1", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "a" : [ "[function (){ return 0; }, function (){ return 0; }]" ] } } } >
- is related to
-
SERVER-16622 RegEx query predicates using the | (vertical bar) character cannot use tight index bounds
- Backlog