Reputation: 47
The following is how it looks like in the collection in my database:
{
row_num: 1,
value: 15
}
{
row_num: 2,
value: 74
}
...
Right now I have the following updated JSON file:
{
row_num: 1,
value: 16
}
{
row_num: 2,
value: 28
}
...
which maps one to one to the data in MongoDB. My question is that is it possible to use MongoDB syntax to update the value in every document in one single row instead of having a loop inside my script to update it?
Upvotes: 1
Views: 496
Reputation: 103355
It's possible when you use the Bulk()
API to do the update instead of sending an update request for each document in the JSON array with a loop. This also
has improved performance in that you will be sending the operations to the server in batches (for example, say a batch size of 500) making your updates more efficient and quicker.
The following demonstrates this approach, the first example uses the Bulk()
API available in MongoDB versions >= 2.6 and < 3.2. It updates all the matched documents in the collection from a given array by modifying the existing value
field to the one in the JSON:
var updatedJsonArray = [
{ "row_num": 1, "value": 16 },
{ "row_num": 2, "value": 28 },
{ "row_num": 3, "value": 43 },
...
{ "row_num": 15478, "value": 9 }
]
MongoDB versions >= 2.6 and < 3.2:
var bulk = db.collection.initializeUnorderedBulkOp(),
counter = 0;
updatedJsonArray.forEach(function (doc) {
bulk.find({ "row_num": doc.row_num }).updateOne({
"$set": { "value": doc.value }
});
counter++;
if (counter % 500 === 0) {
// Execute per 500 operations
bulk.execute();
// re-initialize every 500 update statements
bulk = db.collection.initializeUnorderedBulkOp();
}
})
// Clean up remaining queue
if (counter % 500 !== 0) { bulk.execute(); }
The next example applies to the new MongoDB version 3.2 which has since deprecated the Bulk()
API and provided a newer set of apis using bulkWrite()
.
MongoDB version 3.2 and greater:
var ops = [];
updatedJsonArray.forEach(function(doc) {
ops.push({
"updateOne": {
"filter": { "row_num": doc.row_num },
"update": {
"$set": { "value": doc.value }
}
}
});
if (ops.length === 500) {
db.collection.bulkWrite(ops);
ops = [];
}
})
if (ops.length > 0)
db.collection.bulkWrite(ops);
Upvotes: 1