Home > database >  how can I modify a field name / key in a nested array of objects in mongodb?
how can I modify a field name / key in a nested array of objects in mongodb?

Time:08-25

I have a mongodb collection with a number of objects like this:

{
 "_id" : "1234", 
 "type" : "automatic", 
 "subtypes" : [
    {
     "_id" : "dfgd",
     "name" : "test subtype", 
     "subjetRequired" : true,
    },
    {
     "_id" : "dfgd",
     "name" : "test subtype2", 
     "subjetRequired" : false,
    }
  ],
 "anotherField" : "some value"
}

As you can see, one of the keys in the subtypes array is incorrectly spelled - "subjetRequired" instead of "subjectRequired".
I want to correct that key name. How can I do that.
I'll preface this by saying I've not worked with mongodb very much in the past.
After a lot of researching, the best I could come up with is the following (which doesn't work):

function remap(doc) {
     subtypes = doc.subtypes;
     var count = 0;
     subtypes.forEach(function(subtype){
         db.taskType.update({"_id": subtype._id}, {
             $set: {"subtypes.subjectRequired" : subtype.subjetRequired},
             $unset: {"subtypes.subjetRequired": 1}
         });
     }
     )
}

db.taskType.find({"subtypes.subjetRequired":{$ne:null}}).forEach(remap);

This doesn't work.
I know the loop is correct, as if I replace the other logic with print statements I can access and print the fields who's names I want to modify.
What am I doing wrong here?

CodePudding user response:

You can use this update and avoid using any code, it's also stable so you can execute it multiple times with no fear.

db.collection.updateMany({
  "subtypes.subjetRequired": {
    $exists: true
  }
},
[
  {
    $set: {
      subtypes: {
        $map: {
          input: "$subtypes",
          in: {
            $mergeObjects: [
              "$$this",
              {
                subjectRequired: "$$this.subjetRequired",
                
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: "subtypes.subjetRequired"
  }
])

Mongo Playground

CodePudding user response:

I could modify your loop to override the whole array of subtypes:

function remap(doc) {
  correctSubtypes = doc.subtypes.map(({ subjetRequired, ...rest }) => ({
    ...rest,
    subjectRequired: subjetRequired,
  }));
  var count = 0;
  db.taskType.findByIdAndUpdate(doc._id, {
    $set: {
      subtypes: correctSubtypes,
    },
  });
}
  • Related