我有一个最新的mongodb 3.2,并且有许多具有timeStamp的项目的集合。
需要将毫秒转换为Date对象,现在我使用此函数:
db.myColl.find().forEach(function (doc) {
doc.date = new Date(doc.date);
db.myColl.save(doc);
})
更新2百万行需要很长时间。
我尝试使用updateMany(似乎速度非常快),但我如何才能访问当前文档?有没有机会使用updateMany重写上面的查询?
谢谢。
答案 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时(没有数据传递给客户端)。