Home > Back-end >  In mongoDb, how can I rename a field nested like object-> object -> array -> object -> f
In mongoDb, how can I rename a field nested like object-> object -> array -> object -> f

Time:09-22

Sounds messy, I know.
The document I'm modifying is structured like this:

{
   "_id":12345,
   "name":"harold",
   "basicData":{
      "devices":[
         {
            "id":7654,
            "relatedJson":{
               "make":"sony",
               "equipmentID":"asdf"
            }
         },
         {
            "id":9493
         }
      ],
      "car":"toyota"
   }
}

I can't quite get the code right. This is what I have:

db.serviceAgreement.updateMany({"basicData.devices.relatedJson.equipmentID": {$exists: true}},
    [
        {
            $set: {
                "basicData.devices": {
                    $map: {
                        input: "$basicData.devices", in: {
                            $mergeObjects: ["$$this.relatedJson",
                                {equipmentId: "$$this.relatedJson.equipmentID",}]
                        }
                    }
                }
            }
        },
        {
            $unset: "basicData.devices.relatedJson.equipmentID"
        }

    ])

So my understanding of this script is that I'm calling $set to set the field basicData.devices, then I'm setting it to that same list, but before I do that I'm merging the documents relatedJson and a new document {equipmentId : "$$this.relatedJson.equipmentID",} which has the value equipmentId set to the same value as the equipmentID in the relatedJson object.
Then, I'm replacing the relatedJson document with the newly created equipmentId (not my intention).
And finally, deleting the original equipmentID - which doesn't actually exist any more because I've replaced the whole relatedJson object.

How can I insert the new equipmentId into the relatedJson object, instead of replacing it entirely.

I have tried variations of the above script that do all sorts of things, inserting a copy of relatedJson into itself, inserting a copy of devices into relatedJson, deleting everything inside devices, but I can't get it to do what I want.
I feel I'm close to a solution, and maybe I need to modify the $input: but I can't figure out how, or maybe my approach is totally wrong.
Any help would be greatly appreciated.

The end result should be the same document, but relatedJson.equipmentID should be renamed relatedJson.equipmentId (with a lower-case 'd' at the end);

CodePudding user response:

You're close, you just had some syntax issues.

The update should look like this:

db.collection.updateMany({"basicData.devices.relatedJson.equipmentID": {$exists: true}},
[
  {
    $set: {
      "basicData.devices": {
        $map: {
          input: "$basicData.devices",
          in: {
            $mergeObjects: [
              "$$this",
              {
                $cond: [
                  {
                    $ne: [
                      "$$this.relatedJson",
                      undefined
                    ]
                  },
                  {
                    relatedJson: {
                      $mergeObjects: [
                        "$$this.relatedJson",
                        {
                          equipmentId: "$$this.relatedJson.equipmentID"
                        }
                      ]
                    }
                  },
                  {}
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: "basicData.devices.relatedJson.equipmentID"
  }
])

Mongo Playground

  • Related