7

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.

profesor79
  • 9,213
  • 3
  • 31
  • 52
Roman
  • 85
  • 7
  • You need to save time of client and server negotiate. [This one may help you.](http://stackoverflow.com/questions/8342725/multiply-field-by-value-in-mongodb/8343147#8343147) – Flying Fisher May 26 '16 at 08:32

2 Answers2

5

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); }
chridam
  • 100,957
  • 23
  • 236
  • 235
1

Current query is the only one solution to set field value by itself or other field value (one could compute some data using more than one field from document).

There is a way to improve performance of that query - when it is executed vis mongo shell directly on server (no data is passed to client).

profesor79
  • 9,213
  • 3
  • 31
  • 52