How to get current document pointer for update in updateMany

I have the latest mongodb 3.2, and there is a collection of many elements that have timeStamp.

Milliseconds need to be converted to a Date object, and now I use this function:

db.myColl.find().forEach(function (doc) { doc.date = new Date(doc.date); db.myColl.save(doc); }) 

It took a very long time to update 2 million rows.

I am trying to use updateMany (it seems very fast), but how can I access the current document? Is it possible to rewrite the request above using updateMany?

Thanks.

+6
source share
2 answers

You can use other bulk update APIs, such as the bulkWrite() method, which allows you to use an iterator to access the document, manage it, add the changed document to the list, and then send the list of update operations in the package to the server for execution.

An approach is shown below in which you would use the forEach() cursor to forEach() over a match and modify each document at the same time, pushing the update operation to a batch of about 1000 documents, which can then be immediately updated using bulkWrite() .

This is as efficient as using updateMany() , since it uses the same basic bulk write operations:

 var cursor = db.myColl.find({"date": { "$exists": true, "$type": 1 }}), bulkUpdateOps = []; cursor.forEach(function(doc){ var newDate = new Date(doc.date); bulkUpdateOps.push({ "updateOne": { "filter": { "_id": doc._id }, "update": { "$set": { "date": newDate } } } }); if (bulkUpdateOps.length == 1000) { db.myColl.bulkWrite(bulkUpdateOps); bulkUpdateOps = []; } }); if (bulkUpdateOps.length > 0) { db.myColl.bulkWrite(bulkUpdateOps); } 
+2
source

The current query is the only solution to set the field value yourself or another field value (it was possible to calculate some data using more than one field from the document).

There is a way to improve the performance of this request - when it is executed in the mongo shell directly on the server (data is not transmitted to the client).

+1
source

All Articles