Modify stage builders to support subpipeline projections

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.0.0-rc1
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • Fully Compatible
    • ALL
    • QE 2026-07-06
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      For a QSN tree where an embedded join node also has a projection, the stage builders should be able to support preserving the projection when applied to that node. For example, in the query below the subpipeline project is completely discarded. However, note that projections that apply to the base collection seem to work fine.

      Enterprise test> db.a.aggregate({$lookup: {from: "a", localField: "b", foreignField: "b", as: "x", pipeline: [{$project: {b: 1}}]}}, {$unwind: "$x"}).explain().queryPlanner.winningPlan
      {
        isCached: false,
        usedJoinOptimization: true,
        queryPlan: {
          stage: 'NESTED_LOOP_JOIN_EMBEDDING',
          planNodeId: 4,
          costEstimate: 0.19359127036905283,
          cardinalityEstimate: 1,
          estimatesMetadata: { ceSource: 'Metadata' },
          leftEmbeddingField: 'none',
          rightEmbeddingField: 'x',
          joinPredicates: [ 'b = b' ],
          inputStages: [
            {
              stage: 'COLLSCAN',
              planNodeId: 1,
              costEstimate: 0.09602483518452641,
              cardinalityEstimate: 1,
              estimatesMetadata: { ceSource: 'Metadata' },
              filter: {},
              nss: 'test.a',
              direction: 'forward'
            },
            {
              stage: 'PROJECTION_SIMPLE',
              planNodeId: 3,
              costEstimate: 0.09634243518452641,
              cardinalityEstimate: 1,
              estimatesMetadata: { ceSource: 'Metadata' },
              transformBy: { _id: true, b: true },
              inputStage: {
                stage: 'COLLSCAN',
                planNodeId: 2,
                filter: {},
                nss: 'test.a',
                direction: 'forward'
              }
            }
          ]
        },
        slotBasedPlan: {
          slots: '$$RESULT=s8 env: {  }',
          stages: '[4] project [s8 = makeBsonObj(MakeObjSpec([x = Set(0)], Open, NewObj, 0), s1, s4)] \n' +
            '[4] nlj inner [s1, s3] [] {((s3 ?: null) == (s7 ?: null))} \n' +
            '    left \n' +
            '        [1] scan generic [s1 = record, s2 = recordId] [s3 = b] @"293be7e7-6dea-4723-bd39-54ba46fa6922" \n' +
            '    right \n' +
            '        [2] scan generic [s4 = record, s5 = recordId] [s6 = _id, s7 = b] @"293be7e7-6dea-4723-bd39-54ba46fa6922" \n'
        }
      }

            Assignee:
            Alberto Massari
            Reporter:
            Alya Berciu
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: