Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-75101

when localField contains numeric component it must not be pushed into projection

    • Query Optimization
    • Fully Compatible
    • ALL
    • v7.0, v6.3, v6.0, v5.0, v4.4
    • QO 2023-05-15

      When dependency analysis sees $lookup it adds "localField" content to fields it needs from the original collection. However, when that field includes a numeric component (which we may or may not intended to support as a numeric index) what happens is we push it into transformBy where it's interpreted as a field called "0" because projection doesn't support numeric references to array positions like queries do.

      Create any collection orders and run:

      db.orders.explain().aggregate([ { $lookup: { from: "productsxxx", localField: "products.0.productId", foreignField: "_id", as: "firstProduct" } }, {$match:{a:1}}, {$count:"c"}])
      {
        explainVersion: '1',
        stages: [
          {
            '$cursor': {
              queryPlanner: {
                namespace: 'test.orders',
                indexFilterSet: false,
                parsedQuery: { a: { '$eq': 1 } },
                queryHash: 'C810717C',
                planCacheKey: 'C810717C',
                maxIndexedOrSolutionsReached: false,
                maxIndexedAndSolutionsReached: false,
                maxScansToExplodeReached: false,
                winningPlan: {
                  stage: 'PROJECTION_DEFAULT',
                  transformBy: { 'products.0.productId': 1, _id: 0 },
                  inputStage: {
                    stage: 'COLLSCAN',
                    filter: { a: { '$eq': 1 } },
                    direction: 'forward'
                  }
                },
                rejectedPlans: []
              }
            }
          },
          {
            '$lookup': {
              from: 'productsxxx',
              as: 'firstProduct',
              localField: 'products.0.productId',
              foreignField: '_id'
            }
          },
          {
            '$group': { _id: { '$const': null }, c: { '$sum': { '$const': 1 } } }
          },
          { '$project': { c: true, _id: false } }
        ] // etc
      

      Note transformation {{transformBy: { 'products.0.productId': 1, _id: 0 }}} which will not reach into arrays but rather only match field "0" of "products".

            Assignee:
            matt.boros@mongodb.com Matt Boros
            Reporter:
            asya.kamsky@mongodb.com Asya Kamsky
            Votes:
            0 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              Resolved: