$ group聚合导致BSONobj大小错误(必须小于16mb)

时间:2018-09-09 07:07:22

标签: database mongodb mongodb-query bson

我有一个非常大的人员数据集,该数据集是按以下模式导入的:

_id, personId, city, street, streetNo

使用查询管道的第一阶段,我首先将地址字段分组在一起:

{
    "_id": "$_id", 
    "personId": "$personId",
    "Address": {
        "city": "$city", 
        "street": "$street",
        "streetNo": "$streetNo"
    }
}

第一部分立即完成。

现在,问题是每个人可能有多个地址。我想通过personId将地址分组为一个人:

{
  _id: "$personId",
  Addresses: {
    $addToSet: "$Address"
  }
}

我知道此查询有效且可行。但是,当我运行查询时,过了几分钟,我收到了BSONobj太大的错误。是否因为一个人有太多地址而使文档太大?还是数据集太大? 如何绕过此错误?

1 个答案:

答案 0 :(得分:0)

请查看MongoDB documentation。请特别注意以下几点:

  

当返回游标或将结果存储在集合中时,结果集中的每个文档都受BSON文档大小限制(当前为16兆字节);如果任何单个文档超出BSON文档大小限制,该命令将产生错误。

以及:

  

流水线级的RAM限制为100 MB。如果阶段超出此限制,则MongoDB将产生错误。

由此,我们可以推断出16MB的限制错误,表明您超出了文档大小限制。您对一个人的住址过多的评估是正确的。

不幸的是,在不知道您的数据是什么样子或没有完整的聚合管道调用的情况下,建议不多。话虽如此,这就是我会做的:

  1. 尝试执行分组操作,而不是向集合中添加地址,而是获得与某人相关联的地址数之和,例如{$group: {_id: "$personId", total: {$sum: 1}}
  2. 按计数对文档进行排序,以便查看哪些问题最严重,例如{$sort: {total: -1}}
  3. 选择一个有问题的文档,然后搜索personId与文档_id匹配的文档。
  4. 对与该人关联的所有文档进行正常计数,即db.your_collection.find({personId: ...}).count(),然后将此值与汇总中的计数进行比较。
  5. 如果这些计数相似(尤其是当它们相同时),请仔细查看与该人相关联的地址,并尝试看看是否可以找到Addresses集增长如此之大的原因。
  6. 如有可能,请根据您的发现进行优化。