-
Type:
Bug
-
Resolution: Duplicate
-
Priority:
Major - P3
-
None
-
Affects Version/s: 3.6.0-rc1
-
Component/s: Querying
-
None
-
Query
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
When dotted field plan is generated for distinct command, it uses DISTINCT_SCAN without FETCH.
db.orders.find()
{ "_id" : ObjectId("5a006024e946f6d003f4cf93"), "lineitems" : { "returnflag" : "A" } }
{ "_id" : ObjectId("5a006028e946f6d003f4cf94"), "lineitems" : { "returnflag" : "B" } }
{ "_id" : ObjectId("5a006383e946f6d003f4cf96"), "lineitems" : { "otherflag" : 1 } }
/* without indexes */
db.orders.distinct("lineitems.returnflag")
[ "A", "B" ]
db.orders.createIndex({"lineitems.returnflag":1, "lineitems.linestatus" : 1})
/* ok */
db.orders.distinct("lineitems.returnflag")
[ null, "A", "B" ]
/* make index multikey */
db.orders.insert({lineitems:[ {returnflag:"A"}, {returnflag:"B"} ]})
WriteResult({ "nInserted" : 1 })
db.orders.distinct("lineitems.returnflag")
[ "A", "B" ]
Note in case of using non-multikey index we show null (for missing).
On nonMultikey index explain was:
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 0,
"lineitems.returnflag" : 1
},
"inputStage" : {
"stage" : "DISTINCT_SCAN",
"keyPattern" : {
"lineitems.returnflag" : 1,
"lineitems.linestatus" : 1
},
"indexName" : "lineitems.returnflag_1_lineitems.linestatus_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"lineitems.returnflag" : [ ],
"lineitems.linestatus" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"lineitems.returnflag" : [
"[MinKey, MaxKey]"
],
"lineitems.linestatus" : [
"[MinKey, MaxKey]"
]
}
}
},
hence picking up the null index value (which represented missing).
After the insert, it's:
"winningPlan" : {
"stage" : "COLLSCAN",
"direction" : "forward"
},
This change seems due to SERVER-2104 or SERVER-3173?
It's a correctness regression. Here's plan from 3.4.6 which correctly does not return NULL:
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 0,
"lineitems.status" : 1
},
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "DISTINCT_SCAN",
"keyPattern" : {
"lineitems.status" : 1,
"lineitems.date" : 1
},
"indexName" : "lineitems.status_1_lineitems.date_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"lineitems.status" : [ ],
"lineitems.date" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"lineitems.status" : [
"[MinKey, MaxKey]"
],
"lineitems.date" : [
"[MinKey, MaxKey]"
]
}
}
}
},
3.4 correctly returns no "null" with or without the index.
- duplicates
-
SERVER-14832 Distinct command result set may include or exclude null/undefined depending on presence of index
-
- Needs Scheduling
-