改变流星中mongodb集合的结构

时间:2016-01-09 12:23:06

标签: javascript mongodb meteor

我必须更改集合的文档结构。基于这篇文章(MongoDB/Meteor: Add unique ID to every array element),我使用了代码:

Collection.find({}).forEach(function (doc) {
    addId(doc.group);
});

function addId(obj) {
    if (Object.prototype.toString.call(obj).indexOf('Array') >= 0) {
        obj.forEach(function(item) {
            item.id = item.id || Random.id();
            addId(item);
        });
    }
    else if (typeof obj == 'object') {
        Object.keys(obj).forEach(function(key) {
            addId(obj[key]);
        });
    }
}

我现在的问题是让Collection正确更新。 addId()功能运行良好。如果我在console.logitem.id,我会收到ID。但是如何进行收集更新?也许这是一个愚蠢的问题,但我真的坚持这件事......

Collection.update({ _id: doc._id }, { ???? } );

背景信息

我想为每个group元素和每个data元素添加一个ID:

{
    "_id" : "wLXDvjDvbsxzfxabR",
    "group" : [
        {
            "title" : "title 1",
            "data" : [
                {
                    "note" : "text"
                }
            ]
        },
        {
            "title" : "title 2",
            "data" : [
                {
                    "note 1" : "text"
                },
                {
                    "note 2" : "text"
                },
                {
                    "note 3" : "text"
                }
            ]
        }
    ]
}

结果应该是(对于集合中的每个文档)

{
    "_id" : "wLXDvjDvbsxzfxabR",
    "group" : [
        {
            "id" : "dfDFSfdsFDSfdsFws",
            "title" : "title 1",
            "data" : [
                {
                    "id" : "efBDEWVvfdvsvsdvs",
                    "note" : "text"
                }
            ]
        },
        {
            "id" : "fdsfsFDSFdsfFdsFd",
            "title" : "title 2",
            "data" : [
                {
                    "id" : "WVvfsvVFSDWVDSVsv",
                    "note 1" : "text"
                },
                {
                    "id" : "qqdWSdksFVfSVSSCD",
                    "note 2" : "text"
                },
                {
                    "id" : "MZgsdgtscdvdsRsds",
                    "note 3" : "text"
                }
            ]
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

您可以通过使用 Bulk API 操作来执行此更新。这些允许执行批量更新操作,这些操作只是服务器顶部的抽象操作,可以轻松构建批量操作,从而简化您的更新。这些批量操作主要有两种形式:

  • 订购批量操作。这些操作按顺序执行所有操作,并在第一次写入错误时执行错误。
  • 无序批量操作。这些操作并行执行所有操作并聚合所有错误。无序批量操作不保证执行顺序。

您可以通过Mongo.Collection上的 rawCollection rawDatabase 方法获取npm MongoDB驱动程序中的集合和数据库对象的原始访问权限:

var bulkOp = Collection.rawCollection().initializeUnorderedBulkOp(),
    counter = 0;

Collection.find({}).forEach(function(doc) {
    var changedObj = addId(doc);    
    bulkOp.find({"_id": doc._id}).updateOne({ "$set": changedObj });

    counter++;
    if (counter % 1000 == 0) {
        // Execute per 1000 operations and re-initialize every 1000 update statements
        bulkOp.execute(function(e, r) {
            console.info('r.nMatched', r.nMatched, 'r.nModified', r.nModified);
        });
        bulkOp = Collection.rawCollection().initializeUnorderedBulkOp();
    }
}); 

// Clean up queues
if (counter % 1000 != 0){
    bulkOp.execute(function(e, r) {
        console.info('r.nMatched', r.nMatched, 'r.nModified', r.nModified);
    });
}


function addId(obj) {
    if (Object.prototype.toString.call(obj).indexOf('Array') >= 0) {
        obj.forEach(function(item) {
            item.id = item.id || Random.id();
            addId(item);
        });
    }
    else if (typeof obj == 'object') {
        Object.keys(obj).forEach(function(key) {
            addId(obj[key]);
        });
    }   
    return obj;
}