2

Document Structure

{
  _id: 5,
  grades: [
     { grade_ : 80, mean: 75, std: 8 },
     { mean: 90, std: 5 },
     { mean: 85, std: 3 }
  ]
}

As per above document structure in mongodb i want rename key grade_ to grade

db.collection.update({"_id":5},{"$rename":{"grades.grade_":"grades.grade"}},{"upsert":false,"multi":true})

which gives below error

"writeError" : {
        "code" : 28,
        "errmsg" : "cannot use the part (grades of grades.grade_) to traverse the element ({grades: [ { grade_: 80.0, mean: 75.0, std: 8.0 }, { mean: 90.0, std: 5.0 }, { mean: 85.0, std: 3.0 } ]})"
    }

I want to rename key grade_ to grade, expected output

{
  _id: 5,
  grades: [
     { grade : 80, mean: 75, std: 8 },
     { mean: 90, std: 5 },
     { mean: 85, std: 3 }
  ]
}

2 Answers 2

4

As per MongoDB documentation: ($rename does not work if these fields are in array elements.)

For fields in embedded documents, the $rename operator can rename these fields as well as move the fields in and out of embedded documents. $rename does not work if these fields are in array elements.

So, you need to write your custom logic to update.

db.collection.find({
  "grades.grade_": { $exists : 1 }
}).forEach( function( doc ) {
  for( i=0; i < doc.grades.length; i++ ) {
    if(doc.grades[i].grade_ != undefined) {
      doc.grades[i].grade = doc.grades[i].grade_;
      delete doc.grades[i].grade_;
    }
  }
  db.collection.update({ _id : doc._id }, doc);
});
Sign up to request clarification or add additional context in comments.

2 Comments

Is the space between grades and grade_ intentional? Line two of your example
@Jacques Must be some typo, Thank you to point out. But, it will not affect the end result
4

$rename do not works in an array. So,you can use Aggregate framework's $addField to rename fields in an array.

db.collection.aggregate([
  {
    $addFields: {
      grades: {
        $map: {
          input: "$grades",
          as: "grade",
          in: {
            grade: "$$grade.grade_",
            mean: "$$grade.mean",
            std: "$$grade.std"
          }
        }
      }
    }
  }
])

Output:

[
  {
    "_id": 5,
    "grades": [
      {"grade": 80,"mean": 75,"std": 8},
      {"mean": 90,"std": 5},
      {"mean": 85,"std": 3}
    ]
  }
]

3 Comments

Clink the link and run it, if you want to test it by yourself. mongoplayground.net/p/8FbX6sBrhA3
This solution will not work for me, as it will require to add all the possible keys in $map.in object. In my case there can be more than 400 possible keys
@MilanRegmi I am trying to do similar aggregation and having issues. can you help me here stackoverflow.com/questions/61873974/…

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.