0

I want to set a field on the basis of an existing field. Like:

db.attendances.find().forEach(function(attendance) {
        var entryTime = attendance["entryTime"];
        var exitTime = attendance["exitTime"];

        if(entryTime != null) {
            var entryTimeMillis = entryTime.getTime();
            attendance["entryTimeMillis"] = entryTimeMillis;
        }

        if(exitTime != null) {
            var exitTimeMillis = exitTime.getTime();
            attendance["exitTimeMillis"] = exitTimeMillis;
        }

        db.attendances.save(attendance);
});

I have about 10 Million records in the attendances collection. Is there a way I can execute this faster as this will take a lot of time for 10 Million records?

The function is just converting an existing ISODate field to milliseconds and saving it as another field.

After a comment, I tried bulkWrite:

try {
    db.attendances.bulkWrite(
        [{
            updateMany : {
                "filter" : { "entryTime" : { $exists : true } },
                "update" : { $set : { "entryTimeMillis" : "$entryTime.getTime()" } }
            }
        }]
    );
} catch (e) {
    print(e);
}

But of course "$entryTime.getTime()" is not correct as that won't be evaluated and it doesn't work without the ". What do I do?

Shubham A.
  • 2,446
  • 4
  • 36
  • 68
  • Have you looked at using [`bulkWrite`](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite)? – JohnnyHK Apr 25 '18 at 12:39
  • @JohnnyHK Tried it and added a sample query. Can you tell how can I evaluate `entryTime.getTime()` under `$set` ? – Shubham A. Apr 25 '18 at 12:48
  • You can't. You'd still have to build up an array of `updateOne` operations programmatically and then submit that batch of updates to `bulkWrite`. – JohnnyHK Apr 25 '18 at 12:51
  • This means that I will have to traverse over all the documents! – Shubham A. Apr 25 '18 at 12:52
  • There are pretty clear examples on the marked duplicate. There is no way to refer to the existing value of a field in a document within an update ( aside from the atomic `$inc, $mul` etc ) and even those are directly on one field. There have been examples of `bulkWrite()` or general Bulk API usage up on here for some time. You can actually do the math to extract the milliseconds value in a aggregation pipeline if you intend to write to a new collection. – Neil Lunn Apr 25 '18 at 13:01
  • 1
    See [Group result by 15 minutes time interval in MongoDb](https://stackoverflow.com/questions/26814427/group-result-by-15-minutes-time-interval-in-mongodb) for an example of extracting the "milliseconds" value if you choose the aggregation route. In fact, it probably might even bring into question why you think you need to write this into a separate document field anyway, since the internal format of a BSON Date is in fact the "milliseconds since epoch". – Neil Lunn Apr 25 '18 at 13:03

0 Answers0