Search code examples
mongodbmongoosemongodb-querynosqlmongodb-update

MongoDB - How to rename the specific field from list of unstructured array field?


I have several documents as given below. Now I need to do rename the middlename field into mid_name if middlename exists in the document.

{
    "id":"abc",
    "name":[
      {
          "first_name":"abc",
          "last_name":"def"
      },
      {
          "first_name":"ghi",
          "last_name":"mno",
          "middilename":"xyz"
      }
    ]
}

This is something that I expect it to be.

{
    "id":"abc",
    "name":[
      {
          "first_name":"abc",
          "last_name":"def"
      },
      {
          "first_name":"ghi",
          "last_name":"mno",
          "mid_name":"xyz"
      }
    ]
}

And this is what I have done but it throws the error.

db.md_carrierInformation.updateMany({"name.middlename":{$exists:true}}, {$rename:{"name.$.middlename":"name.mid_name"}})

ERROR

MongoServerError: The source field for $rename may not be dynamic: name.$.middlename


Solution

  • Work on the update with the aggregation pipeline.

    1. $set - Set name array field.

      1.1. $map - Iterate each item in name array and return new array.

      1.2. $cond - Condition for checking current document's middlename is not existed.

      1.2.1. If true, with merge current document with the document with field mid_name via $mergeObjects.

      1.2.2. If false, remain the existing document.

    2. $unset - Remove field for name.middlename.

    db.md_carrierInformation.updateMany({
      "name.middlename": {
        $exists: true
      }
    },
    [
      {
        $set: {
          "name": {
            $map: {
              input: "$name",
              in: {
                $cond: {
                  if: {
                    $ne: [
                      "$$this.middlename",
                      undefined
                    ]
                  },
                  then: {
                    $mergeObjects: [
                      "$$this",
                      {
                        mid_name: "$$this.middlename"
                      }
                    ]
                  },
                  else: "$$this"
                }
              }
            }
          }
        }
      },
      {
        $unset: "name.middlename"
      }
    ])
    

    Sample Mongo Playground