There is a Student collection in my Database as below.
Mongodb Student Collection :
{
name : 'Rahul',
age : '15'
}
{
name : 'Ajay',
age : '25'
}
{
name : 'Pinku',
age : '43'
}
{
name : 'Vinod',
age : '30'
}
I am getting an array of data after making a callout to external system for the above students.
[
{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}
]
My task is to update the Students collection record, with the marks of matching student. Is there a way i can do it in one dml operation, instead of looping through each student document and updating it with marks.
Output should be: Mongod Student Collection :
{
name : 'Rahul',
age : '15',
marks : 80
}
{
name : 'Ajay',
age : '25',
marks : 20
}
{
name : 'Pinku',
age : '43',
marks : 12
}
{
name : 'Vinod',
age : '30',
marks : 50
}
Note : I want to do this inside MondbDB Realm UI, to automate some functionality.
CodePudding user response:
Query
- pipeline update requires MongoDB >= 4.2
- students-grades :
put this variable on reduce "input"[{'name':'Ajay','marks':20}, {'name':'Pinku','marks':12}, {'name':'Vinod','marks':50}, {'name':'Rahul','marks':80}]
- find the documents where name is in the array (its best to have an index on name)
- instead of
["Ajay", "Pinku", "Vinod", "Rahul"]
use something likeget-names(students-grades)
with your driver code $reduce
thestudents-grades
, to find for each name the mark all have a mark because they passed the find
update(
{"name": {"$in": ["Ajay", "Pinku", "Vinod", "Rahul"]}},
[{"$set":
{"mark":
{"$reduce":
{"input":
[{"name": "Ajay", "marks": 20}, {"name": "Pinku", "marks": 12},
{"name": "Vinod", "marks": 50}, {"name": "Rahul", "marks": 80}],
"initialValue": "$$REMOVE",
"in":
{"$cond":
[{"$eq": ["$$this.name", "$name"]},
"$$this.marks",
"$$value"]}}}}}],
{"multi": true})
CodePudding user response:
bulkWrite would be useful in this situation. Map over the input array to generate an array of updateOne operations, then submit them all in bulk.
let input = [
{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}
];
let operations = input.map(function(student){
return {updateOne:{filter:{name:student.name},update:{$set:{marks:student.marks}}
};
db.collection.bulkWrite(operations);