有更快的方法吗?根据我的理解,在使用聚合管道的投影中无法完成。我有预先计算吗?我基本上想要在地图函数中发出部分日期(即一小时)(对于map-reduce)。感谢您抽出宝贵时间帮助我: - )
db.events.find().snapshot().forEach(
function (e) {
e.StartTime = new Date(e.start_time);
db.events.save(e);
}
)
答案 0 :(得分:3)
Bulk Operations API是执行此操作的最快“安全”方式:
var bulk = db.events.initializeOrderedBulkOp();
var count = 0;
db.events.find({ },{ "start_time": 1 }).snapshot().forEach(function(e) {
bulk.find({ "_id": e._id }).updateOne({
"$set": { "StartTime": new Date(e.start_time) }
});
count++;
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.events.initializeOrderedBulkOp();
}
});
if ( count % 1000 != 0 )
bulk.execute();
只有每读取1000个文档,才会从服务器发送和返回一次。因此,减少的流量可以节省大量时间,就像只处理必需的字段一样。
如果这绝对是“一次性”操作,不需要在生产中继续发生,如果你能够这样做,那么你总是可以使用db.eval()
。但请阅读那里的文档和警告,因为这不是一个好主意:
db.eval(function() {
db.events.find({ },{ "start_time": 1 }).snapshot().forEach(function(e) {
db.events.update(
{ "_id": e._id },
{ "$set": { "StartTime": new Date(e.start_time) } }
});
]);
但是如果你正在寻找任何其他方式来“转换”字段,那么目前没有办法让更新操作引用字段的现有值并使用它来更新另一个字段,甚至自己。有$inc
或$bit
等例外,但这些例外具有特定目的。