【问题标题】:How should i update documents, each with different update data set, in mongodb collections我应该如何在 mongodb 集合中更新文档,每个文档都有不同的更新数据集
【发布时间】:2015-01-29 14:31:16
【问题描述】:

我有 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);
});

有没有更好的解决方案?

【问题讨论】:

  • 可以给样例输入+输出文件吗?这将使我们更容易理解您想要做什么。
  • 我的目标是用不同的更新数据集更新 mongodb 中的 600 万个文档。我找不到此场景的任何输入/输出内容。

标签: mongodb


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 2020-11-19
    • 2021-04-19
    • 2018-11-19
    • 1970-01-01
    相关资源
    最近更新 更多