我应该如何更新mongodb集合中的文档,每个文档都有不同的更新数据集

时间:2015-01-29 14:31:16

标签: mongodb

我有mongodb,其中有3个巨大的收藏品说' A'' B'和' C'

每个集合包含大约200万份文档。

每个文档都有某些属性。 每个文档都需要根据某些属性的值进行更新,我可以从中确定该文档的'$set'

目前我对每个集合使用相同的方法。 那就是批量查找所有文件。将它们收集在内存中(我认为是当前方法的罪魁祸首),然后一个接一个地更新它们。

对于第一个集合(具有与其他集合中类似的数据),需要10分钟才能完成。然后接下来的两个收集大约花了2个小时来完成任务或者mongodb客户端早些时候崩溃了。

目前的方法存在一些错误,没有任何需要。

Model.collection.find({}).batchSize(BATCH).toArray(function(err, docs){
  if(err || !docs || !docs.length)
        return afterCompleteOneCollection(err);
  var spec = function(index) {
    if(index % 1000 === 0) console.log('at index : ' + index);
    var toSet = { };
    var toUnset = { };
    var over = function(){
      var afterOver = function(err){
        if(err) return afterCompleteOneCollection(err);
        if(index < docs.length - 1) spec(index+1);
        else afterCompleteOneCollection(null);
      };
      var sb = Object.keys(toSet).length;
      var ub = Object.keys(toUnset).length;
      if(sb || ub) {
        var all = {};
        if(sb) all.$set = toSet;
        if(ub) all.$unset = toUnset;
        Model.collection.update({ _id : docs[index]._id }, all, {}, afterOver);
      } else afterOver(null);
    };
    forEachOfDocument(docs[index], toSet, toUnset, over);
  };
  spec(0);
});

是否有更好的解决方案。?

1 个答案:

答案 0 :(得分:0)

此处http://mongodb.github.io/node-mongodb-native/api-generated/cursor.html#stream的流媒体方法为我工作

这就是我在做的事情:

var stream = Model.collection.find().stream();
stream.on('data', function(data){
  if(data){
    var toSet = { };
    var toUnset = { };
    var over = function(){
      var afterOver = function(err){
        if(err) console.log(err);
      };
      var sb = Object.keys(toSet).length;
      var ub = Object.keys(toUnset).length;
      if(sb || ub) {
        var all = {};
        if(sb) all.$set = toSet;
        if(ub) all.$unset = toUnset;
        Model.collection.update({ _id : data._id }, all, {}, afterOver);
      } else afterOver(null);
    };
    forEachOfDocument(data, toSet, toUnset, over);
  }
});
stream.on('close', function() {
  afterCompleteOneCollection();
});