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

$let inside $map not working properly

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.6.0
    • Component/s: Aggregation Framework
    • Labels:
      None
    • ALL
    • Hide

       

       

      Given the following document:

      db.test.insertOne({
          "_id" : ObjectId("5b27d2c5dd24433254a066a6"),
          "input" : "ab"
      })

      When I run:

       

      db.test.aggregate({
          $project: {
              "result": {
                  $map: {
                      input: { $range: [ 0, { $strLenCP: "$input" } ] }, // array: 0 to number of chars in input string
                      in: { 
                          $let: {
                              vars: { "char": { $substrCP: [ "$input", "$$this", 1 ] } }, // nth character will be stored in "$$char"
                              in: {
                                  $switch: {
                                      branches: [{
                                          case: { $eq: [ "$$char", "a" ] }, then: 1, // this should get matched
                                          case: { $eq: [ "$$char", "b" ] }, then: 2 // but only this one does get matched
                                      }],
                                      default: "$$char"
                                  }
                              }
                          }
                      }
                  }
              } 
          }
      })

      I would expect to receive:

       

      {
          "_id" : ObjectId("5b27d2c5dd24433254a066a6"), 
          "result" : [ 
              1.0, 
              2.0
          ]
      }
      

      However, the result is this:

      {
          "_id" : ObjectId("5b27d2c5dd24433254a066a6"),
          "result" : [ 
              "a", 
              2.0
          ]
      }
      

       

       

      Show
          Given the following document: db.test.insertOne({ "_id" : ObjectId( "5b27d2c5dd24433254a066a6" ), "input" : "ab" }) When I run:   db.test.aggregate({ $project: { "result" : { $map: { input: { $range: [ 0, { $strLenCP: "$input" } ] }, // array: 0 to number of chars in input string in: { $let: { vars: { " char " : { $substrCP: [ "$input" , "$$ this " , 1 ] } }, // nth character will be stored in "$$ char " in: { $ switch : { branches: [{ case : { $eq: [ "$$ char " , "a" ] }, then: 1, // this should get matched case : { $eq: [ "$$ char " , "b" ] }, then: 2 // but only this one does get matched }], default : "$$ char " } } } } } } } }) I would expect to receive:   { "_id" : ObjectId( "5b27d2c5dd24433254a066a6" ), "result" : [ 1.0, 2.0 ] } However, the result is this: { "_id" : ObjectId( "5b27d2c5dd24433254a066a6" ), "result" : [ "a" , 2.0 ] }    

      In v3.6.0, $let inside $map appears to get evaluated at the wrong point in time. See "Steps To Reproduce" for details.

       

            Assignee:
            asya.kamsky@mongodb.com Asya Kamsky
            Reporter:
            daniel.hegener@gmx.net Daniel Hegener
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: