diff --git a/jstests/libs/query/analyze_plan.js b/jstests/libs/query/analyze_plan.js index 99dcd774754..2dab3e700c4 100644 --- a/jstests/libs/query/analyze_plan.js +++ b/jstests/libs/query/analyze_plan.js @@ -171,7 +171,7 @@ function isPlainObject(value) { return value && typeof value == "object" && value.constructor === Object; } -const kExplainChildFieldNames = [ +export const kExplainChildFieldNames = [ "inputStage", "inputStages", "thenStage", diff --git a/jstests/query_golden/expected_output/featureFlagSbeFull/basic_joins.md b/jstests/query_golden/expected_output/featureFlagSbeFull/basic_joins.md index cc45dfd3b0c..e6f83f5098c 100644 --- a/jstests/query_golden/expected_output/featureFlagSbeFull/basic_joins.md +++ b/jstests/query_golden/expected_output/featureFlagSbeFull/basic_joins.md @@ -73,856 +73,218 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 2. Basic example with two joins and suffix ### No join opt ### Pipeline @@ -1015,1126 +377,245 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 3. Basic example with referencing field from previous lookup ### No join opt ### Pipeline @@ -2208,822 +689,202 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 4. Basic example with 3 joins & subsequent join referencing fields from previous lookups ### No join opt ### Pipeline @@ -3119,1117 +980,281 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "none" + | rightEmbeddingField: "y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign2] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 9, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 5. Basic example with 3 joins & subsequent join referencing nested paths ### No join opt ### Pipeline @@ -4320,1053 +1345,262 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "w.y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [c = x.c] + | leftEmbeddingField: "w.y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [x.c = c] + | leftEmbeddingField: "none" + | rightEmbeddingField: "w.y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign3] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` diff --git a/jstests/query_golden/expected_output/sbeDisabled/basic_joins.md b/jstests/query_golden/expected_output/sbeDisabled/basic_joins.md index 2706aba3033..5d45005d75e 100644 --- a/jstests/query_golden/expected_output/sbeDisabled/basic_joins.md +++ b/jstests/query_golden/expected_output/sbeDisabled/basic_joins.md @@ -80,856 +80,218 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 2. Basic example with two joins and suffix ### No join opt ### Pipeline @@ -1036,1126 +398,245 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 3. Example with two joins, suffix, and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -2305,1357 +786,270 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 4. Example with two joins and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -3778,1060 +1172,243 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 5. Example with two joins, suffix, and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -4992,1429 +1569,279 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 6. Example with two joins and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -6547,1123 +1974,252 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 7. Basic example with referencing field from previous lookup ### No join opt ### Pipeline @@ -7744,822 +2300,202 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 8. Basic example with 3 joins & subsequent join referencing fields from previous lookups ### No join opt ### Pipeline @@ -8664,1117 +2600,281 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "none" + | rightEmbeddingField: "y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign2] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 9, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 9. Basic example with 3 joins & subsequent join referencing nested paths ### No join opt ### Pipeline @@ -9874,1053 +2974,262 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "w.y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [c = x.c] + | leftEmbeddingField: "w.y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [x.c = c] + | leftEmbeddingField: "none" + | rightEmbeddingField: "w.y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign3] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` diff --git a/jstests/query_golden/expected_output/sbeFull/basic_joins.md b/jstests/query_golden/expected_output/sbeFull/basic_joins.md index de58394db4c..3d1891c747d 100644 --- a/jstests/query_golden/expected_output/sbeFull/basic_joins.md +++ b/jstests/query_golden/expected_output/sbeFull/basic_joins.md @@ -73,856 +73,218 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 2. Basic example with two joins and suffix ### No join opt ### Pipeline @@ -1015,1126 +377,245 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 3. Example with two joins, suffix, and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -2287,1357 +768,270 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 4. Example with two joins and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -3763,1060 +1157,243 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 5. Example with two joins, suffix, and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -4977,1429 +1554,279 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 6. Example with two joins and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -6532,1123 +1959,252 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 7. Basic example with referencing field from previous lookup ### No join opt ### Pipeline @@ -7722,822 +2278,202 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 8. Basic example with 3 joins & subsequent join referencing fields from previous lookups ### No join opt ### Pipeline @@ -8633,1117 +2569,281 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "none" + | rightEmbeddingField: "y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign2] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 9, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 9. Basic example with 3 joins & subsequent join referencing nested paths ### No join opt ### Pipeline @@ -9834,1053 +2934,262 @@ Execution Engine: sbe ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "w.y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [c = x.c] + | leftEmbeddingField: "w.y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [x.c = c] + | leftEmbeddingField: "none" + | rightEmbeddingField: "w.y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign3] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` diff --git a/jstests/query_golden/expected_output/sbeRestricted/basic_joins.md b/jstests/query_golden/expected_output/sbeRestricted/basic_joins.md index 2706aba3033..5d45005d75e 100644 --- a/jstests/query_golden/expected_output/sbeRestricted/basic_joins.md +++ b/jstests/query_golden/expected_output/sbeRestricted/basic_joins.md @@ -80,856 +80,218 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "2312073BEBB7A5E1754E2D03D9CB40B75C126DBF60867D4639E7E281C9E3DFAC", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 2. Basic example with two joins and suffix ### No join opt ### Pipeline @@ -1036,1126 +398,245 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] ``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$y.b" - } -] -``` -### Results -```json -{ "_id" : "bar", "count" : 6 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "8E0DF14D3DA69D8B1CF0361E869369F9C5E5F2F2A5D81998E6800BDA4F997B57", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$y.b", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 3. Example with two joins, suffix, and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -2305,1357 +786,270 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 1, "count" : 2 } -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "39062D46AC66A096B98DB7B9AD3C198F432183DF3436553F59C3EC8B5252F1EA", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 4. Example with two joins and sub-pipeline with un-correlated $match ### No join opt ### Pipeline @@ -3778,1060 +1172,243 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "6E1AD01BB023E5575DBF8997EA4E7E46A5BCCAA49D659AFD0AB18E0D1E797FF4", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 5. Example with two joins, suffix, and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -4992,1429 +1569,279 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 6, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] ``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | PROJECTION_SIMPLE + | transformBy: { "a" : true, "b" : true, "_id" : false } + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - }, - { - "$sortByCount" : "$x.a" - } -] -``` -### Results -```json -{ "_id" : 2, "count" : 2 } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "7D59BE511C0D33652DB26A61DFFA0D36F47580971FB97DF9C3C4BC3A3F52F932", - "stages" : [ - { - "$cursor" : { - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - "stage" : "PROJECTION_SIMPLE", - "transformBy" : { - "_id" : false, - "a" : true, - "b" : true - } - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } - } - }, - { - "$group" : { - "$willBeMerged" : false, - "_id" : "$x.a", - "count" : { - "$sum" : { - "$const" : 1 - } - } - } - }, - { - "$sort" : { - "sortKey" : { - "count" : -1 - } - } - } - ] -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + PROJECTION_SIMPLE + transformBy: { "a" : true, "b" : true, "_id" : false } + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 6. Example with two joins and sub-pipeline with un-correlated $match and $match prefix ### No join opt ### Pipeline @@ -6547,1123 +1974,252 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "y" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | filter: { "d" : { "$lt" : 3 } } + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + filter: { "d" : { "$lt" : 3 } } + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + filter: { "b" : { "$gt" : "aaa" } } + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStage" : { - "direction" : "forward", - "indexBounds" : { - "b" : [ - "(\"aaa\", {})" - ] - }, - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "multiKeyPaths" : { - "b" : [ ] - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "IXSCAN" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - }, - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "y" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | filter: { "a" : { "$gt" : 1 } } + | direction: "forward" + | + FETCH [test.basic_joins_md_foreign2] + + | + IXSCAN [test.basic_joins_md_foreign2] + keyPattern: { "b" : 1 } + indexName: "b_1" + isMultiKey: false + multiKeyPaths: { "b" : [ ] } + isUnique: false + isSparse: false + isPartial: false + direction: "forward" + indexBounds: { "b" : [ "(\"aaa\", {})" ] } +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$match" : { - "a" : { - "$gt" : 1 - } - } - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a", - "pipeline" : [ - { - "$match" : { - "d" : { - "$lt" : 3 - } - } - } - ] - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b", - "pipeline" : [ - { - "$match" : { - "b" : { - "$gt" : "aaa" - } - } - } - ] - } - }, - { - "$unwind" : "$y" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "D2D2550CF530351E25FFDB1BB9DBD96DD0CE98C0FA4082BADF1F9BC9F7579A03", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - "a" : { - "$gt" : 1 - } - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "filter" : { - "d" : { - "$lt" : 3 - } - }, - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "filter" : { - "b" : { - "$gt" : "aaa" - } - }, - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | filter: { "b" : { "$gt" : "aaa" } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | filter: { "d" : { "$lt" : 3 } } + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + filter: { "a" : { "$gt" : 1 } } + direction: "forward" +``` ## 7. Basic example with referencing field from previous lookup ### No join opt ### Pipeline @@ -7744,822 +2300,202 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "x" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign1] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "z", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 5, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 0, "a" : 1, "b" : "foo", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DC5CAF413E9B6B8B5E8B2D3FB91E4D546524BF2707BBE30472D5CA8E12F6637E", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 6, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 8. Basic example with 3 joins & subsequent join referencing fields from previous lookups ### No join opt ### Pipeline @@ -8664,1117 +2600,281 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [c = x.c] +leftEmbeddingField: "z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [b = b] + | leftEmbeddingField: "none" + | rightEmbeddingField: "y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign2] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] ``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "y", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] +leftEmbeddingField: "none" +rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + NESTED_LOOP_JOIN_EMBEDDING [x.a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [c = c] + leftEmbeddingField: "z" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign3] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "y", - "localField" : "b", - "foreignField" : "b" - } - }, - { - "$unwind" : "$y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "z", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$z" - } -] -``` -### Results -```json -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 1, "a" : 1, "b" : "bar", "x" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 0, "a" : 1, "c" : "zoo", "d" : 1 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 0, "b" : "bar", "d" : 2 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -{ "_id" : 2, "a" : 2, "b" : "bar", "x" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 }, "y" : { "_id" : 1, "b" : "bar", "d" : 6 }, "z" : { "_id" : 2, "a" : 2, "c" : "x", "d" : 3 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "DD24FFAE1F16C6C1F5B03939E0C642A797120A2585058C72554C9649BEA427AB", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "inputStage" : { - "indexName" : "b_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "b" : 1 - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "b = b" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "y", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 9, - "rightEmbeddingField" : "z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.c = c] +leftEmbeddingField: "none" +rightEmbeddingField: "z" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [b = b] + leftEmbeddingField: "none" + rightEmbeddingField: "y" + | | + | FETCH [test.basic_joins_md_foreign2] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign2] + | keyPattern: { "b" : 1 } + | indexName: "b_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ## 9. Basic example with 3 joins & subsequent join referencing nested paths ### No join opt ### Pipeline @@ -9874,1053 +2974,262 @@ Execution Engine: classic ``` ### With bottom-up plan enumeration (left-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With bottom-up plan enumeration (right-deep) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "c = x.c" - ], - "leftEmbeddingField" : "w.y", - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [c = x.c] + | leftEmbeddingField: "w.y" + | rightEmbeddingField: "none" + | | | + | | HASH_JOIN_EMBEDDING [a = a] + | | leftEmbeddingField: "none" + | | rightEmbeddingField: "x" + | | | | + | | | COLLSCAN [test.basic_joins_md_foreign1] + | | | direction: "forward" + | | | + | | COLLSCAN [test.basic_joins_md] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration (zig-zag) -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - }, - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - } - ], - "joinPredicates" : [ - "d = w.y.d" - ], - "leftEmbeddingField" : "k.y.z", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [d = w.y.d] +leftEmbeddingField: "k.y.z" +rightEmbeddingField: "none" + | | + | HASH_JOIN_EMBEDDING [x.c = c] + | leftEmbeddingField: "none" + | rightEmbeddingField: "w.y" + | | | + | | COLLSCAN [test.basic_joins_md_foreign3] + | | direction: "forward" + | | + | HASH_JOIN_EMBEDDING [a = a] + | leftEmbeddingField: "none" + | rightEmbeddingField: "x" + | | | + | | COLLSCAN [test.basic_joins_md_foreign1] + | | direction: "forward" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With random order, seed 44, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` ### With random order, seed 44, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true -### With random order, seed 420, nested loop joins -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md] + direction: "forward" ``` +### With random order, seed 45, nested loop joins usedJoinOptimization: true -### With random order, seed 420, hash join enabled -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] ``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "HASH_JOIN_EMBEDDING" - } -} +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" ``` +### With random order, seed 45, hash join enabled usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With fixed order, index join -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "COLLSCAN" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "c = c" - ], - "leftEmbeddingField" : "x", - "rightEmbeddingField" : "w.y", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "k.y.z", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.a = a" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 7, - "rightEmbeddingField" : "none", - "stage" : "NESTED_LOOP_JOIN_EMBEDDING" - } -} -``` usedJoinOptimization: true +``` +NESTED_LOOP_JOIN_EMBEDDING [x.a = a] +leftEmbeddingField: "none" +rightEmbeddingField: "none" + | | + | COLLSCAN [test.basic_joins_md] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [w.y.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | COLLSCAN [test.basic_joins_md_foreign1] + | direction: "forward" + | + NESTED_LOOP_JOIN_EMBEDDING [d = d] + leftEmbeddingField: "k.y.z" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + COLLSCAN [test.basic_joins_md_foreign2] + direction: "forward" +``` ### With bottom-up plan enumeration and indexes -### Pipeline -```json -[ - { - "$lookup" : { - "from" : "basic_joins_md_foreign1", - "as" : "x", - "localField" : "a", - "foreignField" : "a" - } - }, - { - "$unwind" : "$x" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign3", - "as" : "w.y", - "localField" : "x.c", - "foreignField" : "c" - } - }, - { - "$unwind" : "$w.y" - }, - { - "$lookup" : { - "from" : "basic_joins_md_foreign2", - "as" : "k.y.z", - "localField" : "w.y.d", - "foreignField" : "d" - } - }, - { - "$unwind" : "$k.y.z" - } -] -``` -### Results -```json -{ "_id" : 2, "a" : 2, "b" : "bar", "k" : { "y" : { "z" : { "_id" : 0, "b" : "bar", "d" : 2 } } }, "w" : { "y" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } }, "x" : { "_id" : 1, "a" : 2, "c" : "blah", "d" : 2 } } -``` -### Summarized explain -Execution Engine: sbe -```json -{ - "queryShapeHash" : "9226A4FAA10C8790B27D9B5B865D46D0C58179A837F014E6289A34A6EBE76420", - "rejectedPlans" : [ ], - "winningPlan" : { - "inputStages" : [ - { - "inputStages" : [ - { - "inputStages" : [ - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md", - "stage" : "COLLSCAN" - }, - { - "inputStage" : { - "indexName" : "a_1", - "isMultiKey" : false, - "isPartial" : false, - "isSparse" : false, - "isUnique" : false, - "keyPattern" : { - "a" : 1 - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "INDEX_PROBE_NODE" - }, - "nss" : "test.basic_joins_md_foreign1", - "stage" : "FETCH" - } - ], - "joinPredicates" : [ - "a = a" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "x", - "stage" : "INDEXED_NESTED_LOOP_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign3", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "x.c = c" - ], - "leftEmbeddingField" : "none", - "rightEmbeddingField" : "w.y", - "stage" : "HASH_JOIN_EMBEDDING" - }, - { - "direction" : "forward", - "filter" : { - - }, - "nss" : "test.basic_joins_md_foreign2", - "stage" : "COLLSCAN" - } - ], - "joinPredicates" : [ - "w.y.d = d" - ], - "leftEmbeddingField" : "none", - "planNodeId" : 8, - "rightEmbeddingField" : "k.y.z", - "stage" : "HASH_JOIN_EMBEDDING" - } -} -``` +usedJoinOptimization: true +``` +HASH_JOIN_EMBEDDING [w.y.d = d] +leftEmbeddingField: "none" +rightEmbeddingField: "k.y.z" + | | + | COLLSCAN [test.basic_joins_md_foreign2] + | direction: "forward" + | + HASH_JOIN_EMBEDDING [x.c = c] + leftEmbeddingField: "none" + rightEmbeddingField: "w.y" + | | + | COLLSCAN [test.basic_joins_md_foreign3] + | direction: "forward" + | + INDEXED_NESTED_LOOP_JOIN_EMBEDDING [a = a] + leftEmbeddingField: "none" + rightEmbeddingField: "x" + | | + | FETCH [test.basic_joins_md_foreign1] + | + | | + | INDEX_PROBE_NODE [test.basic_joins_md_foreign1] + | keyPattern: { "a" : 1 } + | indexName: "a_1" + | isMultiKey: false + | isUnique: false + | isSparse: false + | isPartial: false + | + COLLSCAN [test.basic_joins_md] + direction: "forward" +``` diff --git a/jstests/query_golden/join_opt/base_coll_reorder_md.js b/jstests/query_golden/join_opt/base_coll_reorder_md.js index a394528b94e..9669fee4699 100644 --- a/jstests/query_golden/join_opt/base_coll_reorder_md.js +++ b/jstests/query_golden/join_opt/base_coll_reorder_md.js @@ -5,10 +5,10 @@ * requires_fcv_83 * ] */ -import {codeOneLine, linebreak, section, subSection} from "jstests/libs/pretty_md.js"; +import {linebreak, section, subSection} from "jstests/libs/pretty_md.js"; import {outputAggregationPlanAndResults} from "jstests/libs/query/golden_test_utils.js"; -import {normalizePlan, getWinningPlanFromExplain} from "jstests/libs/query/analyze_plan.js"; import {checkSbeFullFeatureFlagEnabled} from "jstests/libs/query/sbe_util.js"; +import {prettyPrintWinningPlan, getWinningJoinOrderOneLine} from "jstests/query_golden/libs/pretty_plan.js"; const coll = db[jsTestName() + "_base"]; coll.drop(); @@ -55,49 +55,11 @@ const origParams = assert.commandWorked( ); delete origParams.ok; -function getStageAbbreviation(stageName) { - switch (stageName) { - case "HASH_JOIN_EMBEDDING": - return "HJ"; - case "NESTED_LOOP_JOIN": - return "NLJ"; - case "MERGE_JOIN": - return "MJ"; - default: - return stageName; - } -} - -function formatEmbeddingField(field) { - if (field && field !== "none") { - return field; - } - - return "_"; -} - -function abbreviate(node) { - const abbrev = getStageAbbreviation(node.stage); - if (abbrev == node.stage) { - return abbrev; - } - const l = formatEmbeddingField(node.leftEmbeddingField); - const r = formatEmbeddingField(node.rightEmbeddingField); - const children = node.inputStages.map(abbreviate); - assert.eq(children.length, 2); - return `(${abbrev} ${l} = ${children[0]}, ${r} = ${children[1]})`; -} - -function getJoinOrder(explain) { - const winningPlan = normalizePlan(getWinningPlanFromExplain(explain), false /*shouldPlatten*/); - const x = abbreviate(winningPlan); - return x; -} - function runSingleTest(subtitle, pipeline, seen = undefined) { let joinOrder = undefined; + const explain = coll.explain().aggregate(pipeline); if (seen) { - joinOrder = getJoinOrder(coll.explain().aggregate(pipeline)); + joinOrder = getWinningJoinOrderOneLine(explain); if (seen.has(joinOrder)) { return undefined; } @@ -105,7 +67,7 @@ function runSingleTest(subtitle, pipeline, seen = undefined) { } subSection(subtitle); if (joinOrder) { - codeOneLine(joinOrder, true); + prettyPrintWinningPlan(explain); } else { outputAggregationPlanAndResults(coll, pipeline, {}, true, false); } diff --git a/jstests/query_golden/join_opt/basic_joins_md.js b/jstests/query_golden/join_opt/basic_joins_md.js index bef91d2b8da..1fdb89d49aa 100644 --- a/jstests/query_golden/join_opt/basic_joins_md.js +++ b/jstests/query_golden/join_opt/basic_joins_md.js @@ -5,10 +5,12 @@ * requires_fcv_83 * ] */ +import {assertArrayEq} from "jstests/aggregation/extras/utils.js"; import {line, linebreak, section, subSection} from "jstests/libs/pretty_md.js"; import {outputAggregationPlanAndResults} from "jstests/libs/query/golden_test_utils.js"; import {getQueryPlanner} from "jstests/libs/query/analyze_plan.js"; import {checkSbeFullFeatureFlagEnabled} from "jstests/libs/query/sbe_util.js"; +import {prettyPrintWinningPlan} from "jstests/query_golden/libs/pretty_plan.js"; const coll = db[jsTestName()]; coll.drop(); @@ -39,8 +41,7 @@ assert.commandWorked( ]), ); -function verifyExplainOutput(pipeline, joinOptExpectedInExplainOutput) { - const explain = coll.explain().aggregate(pipeline); +function verifyExplainOutput(explain, joinOptExpectedInExplainOutput) { const winningPlan = getQueryPlanner(explain).winningPlan; if (joinOptExpectedInExplainOutput) { @@ -55,131 +56,100 @@ function verifyExplainOutput(pipeline, joinOptExpectedInExplainOutput) { assert(!("usedJoinOptimization" in winningPlan), winningPlan); } +function getJoinTestResultsAndExplain(desc, pipeline, params) { + subSection(desc); + assert.commandWorked(db.adminCommand({setParameter: 1, ...params})); + return [coll.aggregate(pipeline).toArray(), coll.explain().aggregate(pipeline)]; +} + +function runJoinTestAndCompare(desc, pipeline, params, expected) { + const [actual, explain] = getJoinTestResultsAndExplain(desc, pipeline, params); + assertArrayEq({expected, actual}); + verifyExplainOutput(explain, true /* joinOptExpectedInExplainOutput */); + prettyPrintWinningPlan(explain); +} + function runBasicJoinTest(pipeline) { try { subSection("No join opt"); assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: false})); outputAggregationPlanAndResults(coll, pipeline, {}, true, false, false /* noLineBreak*/); + const noJoinExplain = coll.explain().aggregate(pipeline); const noJoinOptResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, false /* joinOptExpectedInExplainOutput */); + verifyExplainOutput(noJoinExplain, false /* joinOptExpectedInExplainOutput */); - subSection("With bottom-up plan enumeration (left-deep)"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: true})); - assert.commandWorked( - db.adminCommand({ - setParameter: 1, + runJoinTestAndCompare( + "With bottom-up plan enumeration (left-deep)", + pipeline, + { + internalEnableJoinOptimization: true, internalJoinReorderMode: "bottomUp", internalJoinPlanTreeShape: "leftDeep", - }), - ); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const bottomUpLeftDeepResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, bottomUpLeftDeepResults), - "Results differ between no join opt and bottom-up left-deep join enumeration", + }, + noJoinOptResults, ); - subSection("With bottom-up plan enumeration (right-deep)"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalJoinPlanTreeShape: "rightDeep"})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const bottomUpRightDeepResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, bottomUpRightDeepResults), - "Results differ between no join opt and bottom-up right-deep join enumeration", + runJoinTestAndCompare( + "With bottom-up plan enumeration (right-deep)", + pipeline, + {internalJoinPlanTreeShape: "rightDeep"}, + noJoinOptResults, ); - subSection("With bottom-up plan enumeration (zig-zag)"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalJoinPlanTreeShape: "zigZag"})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const bottomUpZigZagResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, bottomUpZigZagResults), - "Results differ between no join opt and bottom-up zig-zag join enumeration", + runJoinTestAndCompare( + "With bottom-up plan enumeration (zig-zag)", + pipeline, + {internalJoinPlanTreeShape: "zigZag"}, + noJoinOptResults, ); - subSection("With random order, seed 44, nested loop joins"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalJoinReorderMode: "random"})); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinOrderSeed: 44})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const seed44NLJResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, seed44NLJResults), - "Results differ between no join opt and seed 44 NLJ", + for (const internalRandomJoinOrderSeed of [44, 45]) { + runJoinTestAndCompare( + `With random order, seed ${internalRandomJoinOrderSeed}, nested loop joins`, + pipeline, + {internalJoinReorderMode: "random", internalRandomJoinOrderSeed}, + noJoinOptResults, + ); + + runJoinTestAndCompare( + `With random order, seed ${internalRandomJoinOrderSeed}, hash join enabled`, + pipeline, + {internalRandomJoinReorderDefaultToHashJoin: true}, + noJoinOptResults, + ); + } + + // Run tests with indexes. + assert.commandWorked(foreignColl1.createIndex({a: 1})); + assert.commandWorked(foreignColl2.createIndex({b: 1})); + + runJoinTestAndCompare( + "With fixed order, index join", + pipeline, + {internalRandomJoinReorderDefaultToHashJoin: false}, + noJoinOptResults, ); - subSection("With random order, seed 44, hash join enabled"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinReorderDefaultToHashJoin: true})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const seed44HJResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, seed44HJResults), - "Results differ between no join opt and seed 44 HJ", + runJoinTestAndCompare( + "With bottom-up plan enumeration and indexes", + pipeline, + {internalJoinReorderMode: "bottomUp", internalJoinPlanTreeShape: "leftDeep"}, + noJoinOptResults, ); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinReorderDefaultToHashJoin: false})); - - subSection("With random order, seed 420, nested loop joins"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: true})); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinOrderSeed: 420})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const seed420NLJResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, seed420NLJResults), - "Results differ between no join opt and seed 420 NLJ", - ); - - subSection("With random order, seed 420, hash join enabled"); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinReorderDefaultToHashJoin: true})); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - const seed420HJResults = coll.aggregate(pipeline).toArray(); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - assert( - _resultSetsEqualUnordered(noJoinOptResults, seed420HJResults), - "Results differ between no join opt and seed 420 HJ", - ); - - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinReorderDefaultToHashJoin: false})); - foreignColl1.createIndex({a: 1}); - foreignColl2.createIndex({b: 1}); - subSection("With fixed order, index join"); - - outputAggregationPlanAndResults(coll, pipeline, {}, true, false, true /* noLineBreak*/); - verifyExplainOutput(pipeline, true /* joinOptExpectedInExplainOutput */); - const seedINLJResults = coll.aggregate(pipeline).toArray(); - assert( - _resultSetsEqualUnordered(noJoinOptResults, seedINLJResults), - "Results differ between no join opt and INLJ", - ); - - subSection("With bottom-up plan enumeration and indexes"); - assert.commandWorked( - db.adminCommand({ - setParameter: 1, - internalJoinReorderMode: "bottomUp", - internalJoinPlanTreeShape: "leftDeep", - }), - ); - outputAggregationPlanAndResults(coll, pipeline, {}, true, false); - const bottomUpINLJResults = coll.aggregate(pipeline).toArray(); - assert( - _resultSetsEqualUnordered(noJoinOptResults, bottomUpINLJResults), - "Results differ between no join opt and INLJ", - ); - - foreignColl1.dropIndex({a: 1}); - foreignColl2.dropIndex({b: 1}); + assert.commandWorked(foreignColl1.dropIndex({a: 1})); + assert.commandWorked(foreignColl2.dropIndex({b: 1})); } finally { // Reset flags. - assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: false})); - assert.commandWorked(db.adminCommand({setParameter: 1, internalRandomJoinReorderDefaultToHashJoin: false})); - assert.commandWorked(db.adminCommand({setParameter: 1, internalJoinReorderMode: "bottomUp"})); - assert.commandWorked(db.adminCommand({setParameter: 1, internalJoinPlanTreeShape: "zigZag"})); + assert.commandWorked( + db.adminCommand({ + setParameter: 1, + internalEnableJoinOptimization: false, + internalRandomJoinReorderDefaultToHashJoin: false, + internalJoinReorderMode: "bottomUp", + internalJoinPlanTreeShape: "zigZag", + }), + ); } } diff --git a/jstests/query_golden/libs/pretty_plan.js b/jstests/query_golden/libs/pretty_plan.js new file mode 100644 index 00000000000..c5c9acc5d39 --- /dev/null +++ b/jstests/query_golden/libs/pretty_plan.js @@ -0,0 +1,123 @@ +/** + * Pretty-printing helpers for query plans in explain. + */ +import {prettyPrintTree} from "jstests/query_golden/libs/pretty_tree.js"; +import {normalizePlan, getWinningPlanFromExplain, kExplainChildFieldNames} from "jstests/libs/query/analyze_plan.js"; + +// +// Helpers used below to get an abbreviated join order. +// + +function getStageAbbreviation(stageName) { + switch (stageName) { + case "HASH_JOIN_EMBEDDING": + return "HJ"; + case "NESTED_LOOP_JOIN": + return "NLJ"; + case "INDEX_NESTED_LOOP_JOIN": + return "INLJ"; + default: + return stageName; + } +} + +function formatEmbeddingField(field) { + if (field && field !== "none") { + return field; + } + return "_"; +} + +function abbreviate(node) { + const abbrev = getStageAbbreviation(node.stage); + if (abbrev == node.stage) { + if (node.nss) { + return `${node.stage} [${node.nss}]`; + } + return abbrev; + } + const l = formatEmbeddingField(node.leftEmbeddingField); + const r = formatEmbeddingField(node.rightEmbeddingField); + const children = node.inputStages.map(abbreviate); + assert.eq(children.length, 2); + return `(${abbrev} ${l} = ${children[0]}, ${r} = ${children[1]})`; +} + +// +// End of helpers. +// + +/** + * Helper function to extract a one line join order from the input plan. + * Useful for checking if this is a duplicate join order. + */ +export function getJoinOrderOneLine(plan) { + const winningPlan = normalizePlan(plan, false /*shouldFlatten*/); + const x = abbreviate(winningPlan); + return x; +} + +/** + * Same as above, but for the winning plan in an 'explain'. + */ +export function getWinningJoinOrderOneLine(explain) { + return getJoinOrderOneLine(getWinningPlanFromExplain(explain)); +} + +// +// Helpers used below to get a query plan pretty-printed as a tree. +// + +function shortenField(node, fieldName) { + return node[fieldName] ? " [" + node[fieldName] + "]" : ""; +} + +function printPlanNode(node) { + // Place any fields with special formatting/ that we don't want in the default output here. + const bannedFieldNames = ["stage", "planNodeId", "nss", "joinPredicates"].concat(kExplainChildFieldNames); + + const entries = Object.entries(node).filter(([f, _]) => !bannedFieldNames.includes(f)); + let str = `${node.stage}${shortenField(node, "nss")}${shortenField(node, "joinPredicates")}\n`; + for (let i = 0; i < entries.length; i++) { + const [f, v] = entries[i]; + if (f == "filter" && Object.entries(v).length == 0) { + // Omit empty filters. + continue; + } + str += `${f}: ${tojsononeline(v)}${i < entries.length - 1 ? "\n" : ""}`; + } + return str; +} + +function getNodeChildren(node) { + let children = []; + for (const [field, entry] of Object.entries(node)) { + if (kExplainChildFieldNames.includes(field)) { + if (Array.isArray(entry)) { + children = children.concat(entry); + } else { + children.push(entry); + } + } + } + return children; +} + +// +// End of helpers. +// + +/** + * Pretty-prints the given plan as a tree. + */ +export function prettyPrintPlan(plan) { + const winningPlan = normalizePlan(plan, false /*shouldFlatten*/); + prettyPrintTree(winningPlan, printPlanNode, getNodeChildren); +} + +/** + * Same as above, but extracts the winning plan from 'explain' to print. + */ +export function prettyPrintWinningPlan(explain) { + return prettyPrintPlan(getWinningPlanFromExplain(explain)); +} diff --git a/jstests/query_golden/libs/pretty_tree.js b/jstests/query_golden/libs/pretty_tree.js new file mode 100644 index 00000000000..85f134dbe61 --- /dev/null +++ b/jstests/query_golden/libs/pretty_tree.js @@ -0,0 +1,68 @@ +/** + * Generic tree-printer for golden tests. + */ +import {code} from "jstests/libs/pretty_md.js"; + +function defaultNodeToString(node) { + return tojsononeline(node); +} + +function defaultGetChildrenForNode(node) { + return node.children || []; +} + +const kWhitespaceSeparator = " "; +const kEdge = "|"; +function prefix(numEdges) { + return (kWhitespaceSeparator + kEdge).repeat(numEdges + 1); +} + +function formatMultilineNodeStr(nodeStr, numEdges) { + const lines = nodeStr.split("\n"); + const edges = "\n" + prefix(numEdges - 1) + kWhitespaceSeparator; + const prevEdges = prefix(numEdges) + "\n"; + return prevEdges + prefix(numEdges - 1) + kWhitespaceSeparator + lines.join(edges); +} + +function formatNodeForTree(nodeStr, depth, numEdges) { + if (depth == 0) { + // Root node. + return nodeStr + "\n"; + } + + return formatMultilineNodeStr(nodeStr, numEdges) + "\n"; +} + +/** + * Main entry point for generating a pretty-printed tree string. + */ +export function prettyTreeString( + node, + nodeLambda = defaultNodeToString, + getChildrenForNode = defaultGetChildrenForNode, + depth = 0, + numEdges = 0, +) { + // Print root. + const printedNode = nodeLambda(node); + let out = formatNodeForTree(printedNode, depth, numEdges); + + // Traverse tree- we print the last child first (highest in the tree). + const children = getChildrenForNode(node); + for (let i = children.length - 1; i >= 0; i--) { + // Increase distance from left & number of edges to print by index of child. + out += prettyTreeString(children[i], nodeLambda, getChildrenForNode, depth + 1, numEdges + i); + } + return out; +} + +/** + * Main entry point for markdown-formatted tree string. + */ +export function prettyPrintTree( + node, + nodeLambda = defaultNodeToString, + getChildrenForNode = defaultGetChildrenForNode, +) { + code(prettyTreeString(node, nodeLambda, getChildrenForNode), ""); +}