1

As the title says, the field I need to modify is nested like this:

basicData.owners.relatedJson.basicData.devices.equipmentID

which owners and devices are both lists.

The object looks like this:

{
  "basicData": {
    "owners": [
      {
        "relatedJson": {
          "basicData": {
            "devices": [
              {
                "equipmentID": "abcd",
                "type": "camera"
              }
            ],
            "otherFieldsBasicData": "other values",
            "evenMoreFieldsBasicData": "other values"
          },
          "otherFieldsRelatedJson": "other values",
          "evenMoreFieldsRelatedJson": "other values"
        }
      }
    ]
  }
}

I want to rename equipmentID to equipmentId.

I've also asked this question, and I've been trying to create a query using that as a starting point, but with no success.

I was able to build a query that could get as far down as the devices list, but. then I wanted to call $set on that list, and I get an error because you can't call set inside $mergeObjects.

I thought there was some way I could use $[] to help iterate through the first array, but I can't get it to work. I think this approach is wrong.
This is what I've ended up with, which doesn't work:

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

Any advice would be greatly appreciated.

1 Answer 1

1

Think you need two $map (with nested) operators.

First $map to iterate basicData.owners array while another $map is used to iterate relatedJson.basicData.devices array.

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

Demo @ Mongo Playground

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for this, OK, this didn't quite work. I have 35 fields that need to be modified, running this query update 1. It updated it correctly, but it ignored all the others for some reason.
It's because the query should be updateMany
Yes, will be updateMany, sorry for typo error.
So the issue here is because this stuff is so nested, I need use $mergeObjects with every nested object (I think). So in your solution because you're only merging with owners all the nested objects we refer to get overwritten with the new object which just contains the path down to devices.
Done update the answer, you need $mergeObjects operator.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.