提问者:小点点

Mongo聚合字符串到ISODate


在集合中,我存储这种文档:

{
    "_id" : ObjectId("55e8a5cba21b9e051eb448d1"),
    "created_at" : "2015-01-01T00:00:24Z",
    ...
}

我想改变类型的created_at从字符串到ISODate为了得到

{
    "_id" : ObjectId("55e8a5cba21b9e051eb448d1"),
    "created_at" : ISODate("2015-01-01T00:00:24Z)",
    ...
}

我找到了一个解决方案:遍历所有集合

db.trial.find().forEach(
    function(doc) { 
        doc.created_at = ISODate(doc.created_at); 
        db.events_January_watch.save(doc);
    }
);

但这非常缓慢且效率低下,我更愿意使用聚合管道$out

这是我尝试的:

db.trial.aggregate(
    [
        {
            $project: {
                created_at : "$created_at",                                     
                created_at_iso: {$add: ISODate("$created_at_noTime") }
            }
        },
        {
            $out: "trialIso"
        }
    ],
    {
        allowDiskUse: true
    }
);

抛出:E QUERY错误:无效的ISO日期

我不明白为什么自从

ISODate("2015-01-01T00:00:24Z")

在mongo外壳中完美工作。

(这是因为$created_at变量尚未在聚合管道中设置吗?)


共1个答案

匿名用户

最好的方法是使用“批量”操作

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