【问题标题】:$addToSet used too much memory and cannot spill to disk. Memory limit: 104857600 bytes$addToSet 使用了太多内存,无法溢出到磁盘。内存限制:104857600 字节
【发布时间】:2023-03-15 15:22:01
【问题描述】:
[
  {
    $match: {
      $and: [
        {
          $or: [
            { assignee: 'eaa68f83-5024-4a8e-93f0-4b849d598585' },
            { parent: 'eaa68f83-5024-4a8e-93f0-4b849d598585' },
          ],
        },
        { $and: [{ stage: 'COMPLETE' }] },
      ],
    },
  },
  { $group: { _id: null, valueSet: { $addToSet: '$_id' } } },
  { $project: { key: null, value: { $size: '$valueSet' } } },
]

由于记录数 ($_id) 很大,我得到以下错误。

$addToSet 使用了太多内存,无法溢出到磁盘。内存限制:104857600字节

有什么解决办法吗?

【问题讨论】:

  • 这是聚合的一部分吗?如果是这样,请提供完整的汇总和文档样本。如果没有,只需对您的收藏进行计数,就像这段代码一样。
  • @matthPen 更新了 sn-p。组前有比赛阶段
  • 你能提供一些文档样本吗?
  • @matthPen 这里是示例 - mongoplayground.net/p/DjgEBXEDxrg 问题是文档数为 4M+,因此 $addToSet 操作失败。
  • 尝试添加{ "allowDiskUse" : true }

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

默认情况下,对于聚合管道中的任何单个 $push 或 $addToSet 操作,内存限制为 100MB。

在 MongoDB 3.6.17、4.0.14 和 4.2.3 中添加了这些限制以及更改默认值的选项。见https://jira.mongodb.org/browse/SERVER-44869

编辑

想了一会儿,我意识到最终结果是 value 将是管道中文档的唯一 _id 值的计数。这可以通过不使用 $addToSet 以更具可扩展性的方式获得。

不要按null 分组并将每个_id 添加到一个集合中,而是按_id 分组并计算结果中的文档数。

  { $group: { _id: '$_id' } },
  { $count: 'value' },
  {
    $project: {
      key: null,
      value: 1,
    },
  },

【讨论】:

  • 感谢您的帮助!有没有办法我们可以在 mongdb 版本 3.6.9 中设置 internalQueryMaxAddToSetBytes ? 3.6.9 不支持管理命令db.adminCommand({setParameter: 1, internalQueryMaxAddToSetBytes: newLimit})
  • 您确定您使用的是 3.6.9 吗?您在标题中提到的内存限制错误消息直到 3.6.17 才引入
  • 我在分片上仔细检查了它,它是 3.6.19,我能够更改配置并且它有效。谢谢@Joe
  • 但是当 mongo 分片重新启动时,设置恢复为 100MB。我们如何设置这个永久的?
  • 在配置文件中设置参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2023-03-31
  • 2017-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多