|
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; }]"
|
]
|
}
|
}
|
}
|
>
|
|