如何在updateMany中获取要更新的当前文档的指针

时间:2016-05-26 08:10:30

标签: mongodb

我有一个最新的mongodb 3.2,并且有许多具有timeStamp的项目的集合。

需要将毫秒转换为Date对象,现在我使用此函数:

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

更新2百万行需要很长时间。

我尝试使用updateMany(似乎速度非常快),但我如何才能访问当前文档?有没有机会使用updateMany重写上面的查询?

谢谢。

2 个答案:

答案 0 :(得分:4)

您可以利用其他批量更新API,例如 bulkWrite() 方法,它允许您使用迭代器访问文档,对其进行操作,将修改后的文档添加到列表中,然后将批处理中的更新操作列表发送到服务器以供执行。

以下演示了这种方法,您可以使用游标的 forEach() 方法迭代碰撞并修改每个文档,同时将更新操作推送到一批大约1000个文档,然后可以使用 bulkWrite() 方法一次更新。

这与使用 updateMany() 一样高效,因为它使用相同的基础批量写入操作:

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); }

答案 1 :(得分:1)

当前查询是唯一一个单独设置字段值或其他字段值的解决方案(可以使用文档中的多个字段计算一些数据)。

有一种方法可以提高该查询的性能 - 当它直接在服务器上执行mongo shell时(没有数据传递给客户端)。