Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get pointer of current document to update in updateMany

Tags:

mongodb

I have a latest mongodb 3.2 and there is a collection of many items that have timeStamp.

A need to convert milliseconds to 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 very long time to update 2 millions of rows.

I try to use updateMany (seems it is very fast) but how I can get access to a current document? Is there any chance to rewrite the query above by using updateMany?

Thank you.

like image 771
Roman Avatar asked May 26 '16 08:05

Roman


People also ask

How do you update a document?

On the Document Details page, click EDIT / UPDATE.

Which is the correct query to update multiple documents in the Users collection in MongoDB?

In MongoDB, you can update multiple documents in the collection using db. collection. updateMany() method. This method updates all the documents in the collection that match the given filter.

How do I update a single field in MongoDB?

We can use $set and $inc operators to update any field in MongoDB. The $set operator will set the newly specified value while the $inc operator will increase the value by a specified value.


1 Answers

You can leverage other bulk update APIs like the bulkWrite() method which will allow you to use an iterator to access a document, manipulate it, add the modified document to a list and then send the list of the update operations in a batch to the server for execution.

The following demonstrates this approach, in which you would use the cursor's forEach() method to iterate the colloction and modify the each document at the same time pushing the update operation to a batch of about 1000 documents which can then be updated at once using the bulkWrite() method.

This is as efficient as using the updateMany() since it uses the same underlying 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); }
like image 196
chridam Avatar answered Nov 12 '22 18:11

chridam