|
Well unfortunately it turns out this was fixed by accident. The analysis hasn't changed.
> db.c.explain().aggregate([{$unwind: {path: "$b", preserveNullAndEmptyArrays: true}}, {$project: {"a.b.c": "new"}}])
|
{
|
"stages" : [
|
{
|
"$cursor" : {
|
"queryPlanner" : {
|
"plannerVersion" : 1,
|
"namespace" : "test.c",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
|
},
|
"queryHash" : "51371230",
|
"planCacheKey" : "51371230",
|
"winningPlan" : {
|
"stage" : "PROJECTION_DEFAULT",
|
"transformBy" : {
|
"_id" : 1,
|
"a.b" : 1,
|
"b" : 1
|
},
|
"inputStage" : {
|
"stage" : "COLLSCAN",
|
"direction" : "forward"
|
}
|
},
|
"rejectedPlans" : [ ]
|
}
|
}
|
},
|
{
|
"$unwind" : {
|
"path" : "$b",
|
"preserveNullAndEmptyArrays" : true
|
}
|
},
|
{
|
"$project" : {
|
"_id" : true,
|
"a" : {
|
"b" : {
|
"c" : {
|
"$const" : "new"
|
}
|
}
|
}
|
}
|
}
|
],
|
"serverInfo" : {
|
"host" : "borosaurus",
|
"port" : 30000,
|
"version" : "0.0.0",
|
"gitVersion" : "unknown"
|
},
|
"ok" : 1
|
}
|
|
That is, we only request "a.b" from the query layer.
However, now that we use the new projection executor, it will insert "MISSING" values into the 'a' array when performing the a.b: 1 projection. That is, the find layer produces a document like this:
{_id: 5dd5879a56a821798c22ea8a, a: [MISSING, {b: 2}, MISSING, {}]}
|
Then the $project stage applied to the array of length 4 produces the expected result. While I'm not sure there's an observable bug here anymore, I suspect that this would get even more complicated when we introduce the fast-path projection executor that operates over BSON.
I'm going to see what it would take to fix the analysis so that any expression on "a.b.c" requires 'a' in its entirety.
CC david.storch anton.korshunov
|