有没有更快的方法来做到这一点?据我了解,它不能在使用聚合管道的投影中完成。我必须预先计算吗?我基本上想在 map 函数(用于 map-reduce)中发出部分日期(即一个小时)。感谢您花时间帮助我:-)
db.events.find().snapshot().forEach(
function (e) {
e.StartTime = new Date(e.start_time);
db.events.save(e);
}
)
最佳答案
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) } }
});
]);
但是如果您正在寻找任何其他方法来“转换”一个字段,目前还没有办法让更新操作引用一个字段的现有值并使用它来更新另一个字段,甚至是它自己。也有异常(exception),例如 $inc
或 $bit
,但它们有特定的用途。
关于javascript - 从预先存在的字段生成 ISO 日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25438671/