-
Type:
Bug
-
Resolution: Duplicate
-
Priority:
Major - P3
-
None
-
Affects Version/s: 3.2.9, 3.3.15
-
Component/s: Querying
-
None
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
It appears that when querying with $elemMatch a partial index that could satisfy the query is not being considered, resulting in a collection scan.
If a hint is added to use the partial index the execution stats confirm that the index can be used efficiently.
Also if the query is amended to include the $elemMatch predicate covered by the partial index the same efficient plan is selected.
Consider the following test data and partial index:
db.foo.insert({ state: 'active', properties : [{ substatus : 'scheduled', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.insert({ state: 'active', properties : [{ substatus : 'unknown', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.insert({ state: 'active', properties : [{ substatus : 'inprogress', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.insert({ state: 'completed', properties : [{ substatus : 'processed', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.insert({ state: 'completed', properties : [{ substatus : 'returned', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.insert({ state: 'completed', properties : [{ substatus : 'failed', date : ISODate("2016-09-15T19:47:35.255Z") }] })
db.foo.createIndex({
state : 1,
'properties.substatus' : 1
}, {
partialFilterExpression : {
state : 'active',
'properties.substatus' : 'scheduled'
}
})
The following query results in a plan with a collection scan, even though the query can be satisfied by the partial index:
db.foo.find({
state : 'active',
properties : {
$elemMatch : {
substatus : 'scheduled',
date : { $lte : new ISODate() }
}
}
})
However if an index hint is added to use the partial index the correct plan is chosen:
db.foo.find({
state : 'active',
properties : {
$elemMatch : {
substatus : 'scheduled',
date : {
$lte : new ISODate()
}
}
}
}).hint({
state : 1,
'properties.substatus' : 1
})
"stage" : "IXSCAN",
"totalKeysExamined" : 1
"totalDocsExamined" : 1
Also note that if the top-level of the query is modified to include the 'properties.substatus' predicate this same plan is chosen:
db.foo.find({
state : 'active',
'properties.substatus' : 'scheduled',
properties : {
$elemMatch : {
substatus : 'scheduled',
date : {
$lte : new ISODate()
}
}
}
})
Should the winning plan be one that uses the partial index?
- duplicates
-
SERVER-17853 Allow more complex expressions to be specified in partial index document filter
-
- Backlog
-