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

时间:2015-12-25 23:57:24

标签: mongodb

我试图通过制作一个稍后要使用的数据的大型json文件来聚合来自Mongo集合的数据,以便为FreeCodeCamp生成一些统计信息。

我遇到了标题中的错误。似乎没有关于此的大量信息,而这里的其他帖子也没有答案。我使用的是最新版本的MongoDB和驱动程序。

我怀疑可能有更好的方法来运行此聚合,但它在我的集合的子集上运行良好。我的完整系列大约是7GB。

我通过node 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);
  });
});

3 个答案:

答案 0 :(得分:1)

这只意味着您正在构建的结果对象变得太大。此类问题不应受版本影响。 The fix implemented for 2.5.0 only prevents the crash from occurring

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

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

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

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

[12.66, 4.25, 4.003333333333333, 13.51, 13.67]

我不会想象这种方法适合所有人,但希望能帮助那些处于我特殊情况的人。