有没有办法执行更新操作的“干运行”?

时间:2013-05-17 13:44:50

标签: mongodb

我正在更改一个MongoDB集合的架构。 (我一直将日期存储为字符串,现在我的应用程序将它们存储为ISODate;我需要返回并更改所有旧记录以使用ISODate s。)我想我知道如何使用更新来做到这一点,但由于这个操作会影响成千上万的记录,所以我不愿意发出一个我不是100%肯定会运行的操作。是否有任何方法可以对更新进行“干运行”,这些更新将向我显示原始记录以及如何更改的少量记录?


编辑:我最终使用向每条记录添加新字段的方法,然后(在验证数据正确后)重命名该字段以匹配原始字段。它看起来像这样:

db.events.find({timestamp: {$type: 2}})
    .forEach( function (e) {
        e.newTimestamp = new ISODate(e.timestamp);
        db.events.save(e);
    } )

db.events.update({},
    {$rename: {'newTimestamp': 'timestamp'}},
    {multi: true})

顺便说一下,将字符串时间转换为ISODate s的方法最终起作用了。 (我从this SO answer得到了这个想法。)

4 个答案:

答案 0 :(得分:4)

使用您的数据库结构创建测试环境。将少量记录复制到其中。问题解决了。不是你想要的解决方案,我敢肯定。但是,我相信,这是应该使用“测试环境”的确切情况。

答案 1 :(得分:4)

我的建议是将ISODate添加为新字段。一旦确认所有看起来都很好,您就可以取消设置字符串日期。

答案 2 :(得分:2)

选择您要监控的特定记录的ID。放在update {_id:{$in:[<your monitored id>]}}

答案 3 :(得分:0)

另一个选项取决于它会给你造成的开销 - 您可以考虑编写脚本,执行查找操作,添加打印输出或在调试保存操作时运行调试。一旦您获得了信心,就可以应用保存操作。

 var changesLog = [];
var errorsLog = [];
events.find({timestamp: {$type: 2}}, function (err, events) {
    if (err) {
        debugger;
        throw err;
    } else {
        for (var i = 0; i < events.length; i++) {
            console.log('events' + i +"/"+(candidates.length-1));
            var currentEvent = events[i];
            var shouldUpdateCandidateData = false;

            currentEvent.timestamp = new ISODate(currentEvent.timestamp);


            var change = currentEvent._id;
            changesLog.push(change);

            // // ** Dry Run **
            //     currentEvent.save(function (err) {
            //         if (err) {
            //             debugger;
            //             errorsLog.push(currentEvent._id + ", " + currentEvent.timeStamp + ', ' + err);
            //             throw err;
            //         }
            //     });
        }
        console.log('Done');
        console.log('Changes:');
        console.log(changesLog);
        console.log('Errors:');
        console.log(errorsLog);
        return;
    }
});