Mongo aggregation String to ISODate
在一个集合中,我存储了这种文档:
1 2 3 4 5 | { "_id" : ObjectId("55e8a5cba21b9e051eb448d1"), "created_at" :"2015-01-01T00:00:24Z", ... } |
我想将created_at的类型从String更改为ISODate以获得
1 2 3 4 5 | { "_id" : ObjectId("55e8a5cba21b9e051eb448d1"), "created_at" : ISODate("2015-01-01T00:00:24Z)", ... } |
我找到了一种解决方案:遍历所有集合,进行
1 2 3 4 5 6 | db.trial.find().forEach( function(doc) { doc.created_at = ISODate(doc.created_at); db.events_January_watch.save(doc); } ); |
但是这非常慢且效率低下,我更喜欢使用聚合管道$ out
这是我尝试的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | db.trial.aggregate( [ { $project: { created_at :"$created_at", created_at_iso: {$add: ISODate("$created_at_noTime") } } }, { $out:"trialIso" } ], { allowDiskUse: true } ); |
哪个抛出:
E QUERY错误:无效的ISO日期
我不明白为什么
1 | ISODate("2015-01-01T00:00:24Z") |
在mongo shell中完美运行。
(这是因为尚未在聚合管道中设置$ created_at变量吗?)
做到这一点的最佳方法是使用"批量"操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var bulk = db.trial.initializeUnorderedBulkOp(), count = 0; db.trial.find().forEach(function(doc) { bulk.find({"_id": doc._id }).updateOne({ "$set": {"created_at": ISODate(doc.created_at) } }) count++; if (count % 1000 == 0) { // Execute per 1000 operations and re-init bulk.execute(); bulk = db.trial.initializeUnorderedBulkOp(); } }) if (count % 1000 != 0) bulk.execute(); |