S_Nambiar
S_Nambiar

Reputation: 31

MongoDB - Update an Key

I have been trying to update an Object for this collection. Below is the collection. Looking for Server 3.6 version.

Here The ask is Need to update the class name from "HISTORY" to " HISTORY_NEW". Need to do, for some students in the class. Need a query that will select all student records in student collection with "HISTORY" class in it and update them to "HISTORY_NEW ". I have around 30,000 records and not getting a bulk update method.

{
    "_id" : ObjectId("611f90aa43f77a728879c395"),
    "studentId" : "stu1",
    "classes" : {
        "History"  : {
        "TeacherName" : "T1",
        "Marks" : [ 
            {
              "Internal": 15
            }
        ]
    },
        "Geography" : {
            "TeacherName" : "T2",
            "Marks" : [ 
                {
                    "Internal" : 20
                }
            ]
        }
    },
    "updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}

This is the result I am expecting

{
    "_id" : ObjectId("611f90aa43f77a728879c395"),
    "studentId" : "stu1",
    "classes" : {
        "HISTORY_NEW"  : {
        "TeacherName" : "T1",
        "Marks" : [ 
            {
              "Internal": 15
            }
        ]
    },
        "Geography" : {
            "TeacherName" : "T2",
            "Marks" : [ 
                {
                    "Internal" : 20
                }
            ]
        }
    },
    "updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}

.Or is that even possible with the kind of collection above or going via code route?

So far this is what I have, without any success.

Get all students' Ids and then update the Class name. But that is also not working and don't think it is smart to update DB 30,000 times.

var studentIds =[];
db.studentSubject.find({"classes.History":{$exists:true}})
    .forEach(function(u) { studentIds.push(u.studentId) })


studentIds.forEach(function(studentId) {
    var result;

    try {

    result =db.studentSubject.updateOne(
        {studentId:studentId},
        { $set :  {"classes.History": "HISTORY_NEW",}},  
        { upsert: false}); 


    } catch (e) { 
        print(e);
    }

});

Upvotes: 1

Views: 742

Answers (1)

Yong Shun
Yong Shun

Reputation: 51240

From your scenario, you need $rename operator.

As discussed in the comment, you don't need to fetch each document to get studentId and then pass it to update each document. Just bulk update by checking the document has classes.History field.

db.collection.update({
  "classes.History": {
    $exists: true
  }
},
{
  $rename: {
    "classes.History": "classes.HISTORY_NEW"
  }
},
{
  upsert: false,
  multi: true
})

Sample Mongo Playground

Upvotes: 1

Related Questions