gpt4 book ai didi

mongodb - 并行运行 MongoDB 聚合

转载 作者:可可西里 更新时间:2023-11-01 09:15:12 28 4
gpt4 key购买 nike

目前,我正在针对包含用户和事件信息的集合运行聚合。例如:

[
{
$match: {
client: ObjectId('507f1f77bcf86cd799439011'),
location: 'UK'
}
},
{
$group: {
_id: null,
count: {
$sum: 1
}
}
}
]

上面是一个很大的简化,足以说明大约有 20 个不同的变量,例如 location 可以进入 $match 语句。有时这两者之间还有额外的步骤,这就是我使用 $group 进行计数的原因。 (而不是count)

目前我在 client 字段上有一个索引,但还没有在其他字段上创建索引(复合或其他)。由于还有很多其他字段,我不能只为所有内容创建索引 - 太昂贵了。

问题:当客户端的文档数量较少时,这种方法效果很好,但随着数量的增加,聚合必须扫描越来越多的文档。索引将范围向下聚焦,但这还不够。


想法

创建一个名为 p 的附加变量(用于分区),并创建一个复合索引:{ client: 1, p: 1 } p可以是1-n

不是运行上面的管道,而是运行类似的管道 n 次:(对于 p 的所有可能值)

[
{
$match: {
client: ObjectId('507f1f77bcf86cd799439011'),
p: 1, // or 2, 3, etc
location: 'UK'
}
},
{
$group: {
_id: null,
count: {
$sum: 1
}
}
}
]

然后可以在应用程序级别合并所有管道的结果。

使用这种方法,我可以限制每个查询必须执行的扫描次数,理论上可以减少查询时间。

更进一步,这个 p 值可以用作分片键,因此理论上,分析查询可以跨多个分片并行运行。

以前有没有人做过这样的事情?我在这个问题上发现的很少。

最佳答案

对这种方法的早期测试表明它非常非常好。并行运行多个 count 查询意味着“总查询时间”计算现在是:

total time = max(single query time) + combination time

我还没有在大规模上测试过它,但在中等规模上它绝对是一种享受。

有关此测试的简要统计信息:

  • 集合有 250 万份文件
  • 这些文档中有 200k 个具有我关心的 client 参数
  • 我并行运行 4 个查询,每个查询查看不同的文档子集 (~50k)

对于少量扫描,这种方法几乎没有任何好处。但是对于上面的示例,我们得到的总时间减少了2-4x

看起来这种方法在 50-100k 子集大小之间有一个最佳点。

当然,并行运行大量查询会使您可能受到其他 MongoDB 限制。

关于mongodb - 并行运行 MongoDB 聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30515343/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com