【问题标题】:$group aggregation results in BSONobj size error (must be less than 16mb)$group 聚合导致 BSONobj 大小错误(必须小于 16mb)
【发布时间】:2019-02-13 23:12:11
【问题描述】:

我有一个非常大的人员数据集,它是在以下架构中导入的:

_id, personId, city, street, streetNo

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

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

第一部分立即完成。

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

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

我知道这个查询是有效的并且有效。但是当我运行查询时,几分钟后我得到 BSONobj too large 错误。是因为一个人的地址太多导致文档太大吗?还是数据集太大? 如何绕过此错误?

【问题讨论】:

    标签: database mongodb mongodb-query bson


    【解决方案1】:

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

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

    还有:

    流水线阶段的 RAM 限制为 100 兆字节。如果一个stage超过这个限制,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. 如果可能,请根据您的发现进行优化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      相关资源
      最近更新 更多