Details
-
Task
-
Resolution: Unresolved
-
Major - P3
-
None
-
None
-
None
-
Query Execution
-
QE 2023-05-15
-
10
Description
Consider the projection {_id: 0, "a.b.c": 1}. Currently, the projection stage builder will produce the following plan:
[2] project [s6 = traverseP(s4, lambda(l1.0) { |
if isObject(l1.0) |
then makeBsonObj(MakeObjSpec(keep, [], ["a"]), l1.0, traverseP(getField(l1.0, "a"), lambda(l2.0) { |
if isObject(l2.0) |
then makeBsonObj(MakeObjSpec(keep, [], ["b"]), l2.0, traverseP(getField(l2.0, "b"), lambda(l3.0) { |
if isObject(l3.0) |
then makeBsonObj(MakeObjSpec(keep, ["c"], []), l3.0) |
else Nothing |
}, Nothing))
|
else Nothing |
}, Nothing))
|
else Nothing |
}, Nothing)]
|
[1] scan s4 s5 none none none none [] @"9b7f08cc-f7c3-4d13-957a-a824db1bb046" true false |
This plan makes use of the `makeBsonObj` vm instruction. Compare this to the plan generated by the optimizer, which uses keep/dropFields to implement the projection:
plan : [2] project [s2 = |
let [
|
l101.0 = |
if isObject(s1) |
then keepFields(s1, "a") |
else s1 |
]
|
in
|
let [
|
l102.0 = traverseP(getField(l101.0, "a"), lambda(l103.0) { |
let [
|
l104.0 = |
let [
|
l105.0 = |
if isObject(l103.0) |
then move(l103.0) |
else Nothing |
]
|
in
|
if isObject(l105.0) |
then keepFields(move(l105.0), "b") |
else move(l105.0) |
]
|
in
|
let [
|
l106.0 = traverseP(getField(l104.0, "b"), lambda(l107.0) { |
let [
|
l108.0 = |
if isObject(l107.0) |
then move(l107.0) |
else Nothing |
]
|
in
|
if isObject(l108.0) |
then keepFields(move(l108.0), "c") |
else move(l108.0) |
}, Nothing)
|
]
|
in
|
if (exists(l106.0) || isObject(l104.0)) |
then setField(move(l104.0), "b", move(l106.0)) |
else move(l104.0) |
}, Nothing)
|
]
|
in
|
if (exists(l102.0) || isObject(l101.0)) |
then setField(move(l101.0), "a", move(l102.0)) |
else move(l101.0) |
This ticket tracks the work to replace MakeObjSpec with keep/dropFields and to remove MakeObjSpec