Mongodb Mongo聚合和MongoError:异常:BufBuilder试图将()增长到134217728字节,超过64MB限制

Mongodb Mongo聚合和MongoError:异常:BufBuilder试图将()增长到134217728字节,超过64MB限制,mongodb,Mongodb,我正试图通过制作一个大的json数据文件以供以后使用,从而聚合来自Mongo集合的数据,为FreeCodeCamp生成一些统计数据 我遇到了标题中的错误。关于这一点似乎没有太多的信息,这里的其他帖子也没有答案。我正在使用最新版本的MongoDB和驱动程序 我怀疑可能有更好的方法来运行此聚合,但它在我的集合的一个子集上运行良好。我的全部收藏容量约为7GB 我正在通过节点aggScript.js>~/Desktop/output.json运行脚本 以下是相关代码: MongoClient.conne

我正试图通过制作一个大的json数据文件以供以后使用,从而聚合来自Mongo集合的数据,为FreeCodeCamp生成一些统计数据

我遇到了标题中的错误。关于这一点似乎没有太多的信息,这里的其他帖子也没有答案。我正在使用最新版本的MongoDB和驱动程序

我怀疑可能有更好的方法来运行此聚合,但它在我的集合的一个子集上运行良好。我的全部收藏容量约为7GB

我正在通过
节点aggScript.js>~/Desktop/output.json运行脚本
以下是相关代码:

MongoClient.connect(secrets.db, function(err, database) {
  if (err) {
    throw err;
  }

  database.collection('user').aggregate([
    {
      $match: {
        'completedChallenges': {
          $exists: true
        }
      }
    },
    {
      $match: {
        'completedChallenges': {
          $ne: ''
        }
      }
    },
    {
      $match: {
        'completedChallenges': {
          $ne: null
        }
      }
    },
    {
      $group: {
        '_id': 1, 'completedChallenges': {
          $addToSet: '$completedChallenges'
        }
      }
    }
  ], {
    allowDiskUse: true
  }, function(err, results) {
    if (err) { throw err; }
    var aggData = results.map(function(camper) {
      return _.flatten(camper.completedChallenges.map(function(challenges) {
        return challenges.map(function(challenge) {
          return {
            name: challenge.name,
            completedDate: challenge.completedDate,
            solution: challenge.solution
          };
        });
      }), true);
    });
    console.log(JSON.stringify(aggData));
    process.exit(0);
  });
});

这只意味着您正在构建的结果对象变得太大。此类问题不应受到版本的影响

您需要正确筛选($match)以获得结果中所需的数据。也可以用适当的字段分组。结果被放入64MB的缓冲区中。所以减少你的数据。结果中仅显示所需的列。不是完整的文件

您可以将3$match对象合并为单个对象以减少管道

{
  $match: {
    'completedChallenges': {
       $exists: true,
       $ne: null,
       $ne: ""
    }
  }
}

聚合返回包含所有结果数据的单个文档,这将限制可以返回到最大BSON文档大小的数据量

假设您确实需要所有这些数据,有两个选项:

  • 使用
    aggregateCursors
    而不是
    aggregate
    。这将返回一个游标,而不是一个文档,然后您可以对其进行迭代
  • 添加一个阶段作为管道的最后一个阶段。这将告诉mongodb将聚合数据写入指定的集合。aggregate命令本身不返回任何数据,然后可以像查询任何其他集合一样查询该集合

我遇到了这个问题,无法调试该问题,因此最终放弃了聚合方法。相反,我只是遍历每个条目并创建一个新集合。下面是一个精简的shell脚本,可以帮助您理解我的意思:

db.new_collection.ensureIndex({my_key:1}); //for performance, not a necessity
db.old_collection.find({}).noCursorTimeout().forEach(function(doc) {

    db.new_collection.update(
       { my_key: doc.my_key },
       { 
           $push: { stuff: doc.stuff, other_stuff: doc.other_stuff},
            $inc: { thing: doc.thing},
       },
       { upsert: true }
    );

});

我不认为这种方法适用于所有人,但希望它能帮助任何处于我这种特殊情况的人。

“针对2.5.0实施的修复程序只会防止崩溃的发生。”您的部分答案看起来像是从这里复制/粘贴的:,如果您是paraphrasing@JoeRocc:忘记添加链接。现在添加。您还可以编辑答案和添加链接。感谢您的通知。aggregateCursor函数已被删除。aggregate()方法现在具有拆分个性:管道操作的旧varargs管道操作数组作为第一个参数,第二个参数“options”
(例如{allowDiskUsage:true})