$push+$reduce 真的比自定义累加器慢吗?

问题描述 投票:0回答:1

假设我在 MongoDB 集合中有几百万个文档,如下所示:

[
  {
    "timestamp": "2024-01-01T00:00:00Z",
    "schema": "1.0.0",
    "value": 3,
  },
  {
    "timestamp": "2024-01-01T01:00:00Z",
    "schema": "1.2.0",
    "value": -10,
  },
  ...
]

现在,我想使用聚合管道执行以下操作:

因此,所需的输出类似于:

[
    // January bucket
  {
    "bucket": "2024-01-01T00:00:00Z",
    "value": {
      "timestamp": "2024-01-01T01:00:00Z",
      "schema": "1.2.0",
      "absMax": -10
    }
  }
]

显然,默认的

$max
累加器不起作用,因为它有两个问题:

  • 查询绝对最大值时不能保留原始符号
  • 不包含
    timestamp
    schema
    ,只输出数值

因此,我尝试了两种不同的方法来解决这个问题:

  1. 在我的
    $group
    阶段,我使用
    $push
    将所有原始文档推送到
    $raw
    文档中,然后使用
    $reduce
    进行查看。我需要
    $raw
    文档才能始终提供
    timestamp
    schema
  2. 在我的
    $group
    阶段,我使用自定义累加器函数(参见https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator/)来减少每个文档并保留原始
     timestamp
    schema
    位于其状态的绝对最大值旁边。

现在,我遇到以下问题:

  • 解决方案 1 遇到内存问题,因为将数百万个文档推送到 RAM 超出了 MongoDB 每个聚合步骤 100MB RAM 的硬限制
  • 解决方案 2 在代码中看起来确实相当难看,MongoDB 建议不要使用用 javascript 编写的自定义累加器函数。

我用 MongoDB Playgrounds 更新了我的问题:

为了完整起见,仅使用

$min
$max
,但丢失
timestamp
schema
https://mongoplayground.net/p/UegNExWo2np

在大数据集上,解决方案 2 的速度大约是解决方案 1 的两倍。

我是否忽略了什么?

mongodb aggregation-framework
1个回答
0
投票

首先,您可以使用 $dateTrunc

更轻松地进行分组

其次,你不必推

$$ROOT
,使用

{
data: { $push: {timestamp: "$timestamp", schema: "$schema"}},
max: {$max: "$value"}
}

剩下的只是一些装饰。稍后可以提供完整的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.