The '$' operator only updates the first match so given:
db.students.insert({ "_id" : 4, "grades" : [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 95, std: 6 },
{ grade: 90, mean: 85, std: 5 } ]});
To update you need to target with $elemMatch
like so:
db.students.update( { _id: 4, "grades": {$elemMatch: {"grade": 85, "std": 5 }}},
{ $set: { "grades.$.std" : 6 } });
However, you have two grades that match {"grades.grade": 85, "grades.std": 5}
and $
only updates the first so you need to loop until all updated:
db.students.update( { _id: 4, "grades": {$elemMatch: {"grade": 85, "std": 5 }}},
{ $set: { "grades.$.std" : 6 } })
while (db.getLastErrorObj()['n'] > 0) {
db.students.update( { _id: 4, "grades": {$elemMatch: {"grade": 85, "std": 5 }}},
{ $set: { "grades.$.std" : 6 } })
}
Problem 2: Same thing applies - you need to loop to $pull
matching elements:
db.students.update({_id:4,'grades': {$elemMatch: {'grade':85}}}, {'$pull': {'grades': {'grade':85}}})