【发布时间】:2019-01-30 21:54:35
【问题描述】:
我有一个 mongo 集合,其中包含我想要汇总字段的子文档的文档 - 下面是我希望实现的示例
每个文档的大体结构是
{
"pool" : "Foo",
"monthly-figures" : {
"1": {
"a" : 311,
"b" : 1481,
...
"x" : {"a" : 311, "b" : 19.965999999999998},
"y" : {"a" : 200, "b" : 14.174000000000003
}
},
"2": {
"a" : 500,
"b" : 100,
...
"x" : {"a" : 123, "b" : 198},
"y" : {"a" : 200, "b" : 13.7}
},
... // May not all be present
"12": {...}
}
}
}
monthly 存储为对象而不是数组的原因是某些月份可能不存在。
以三个文件为例
{
"pool" : "Foo",
"monthly-figures" : {
"1": {
"a" : 10,
"b" : 20,
...
"x" : {"a" : 15, "b" :30}
}
},
"2": {
"a" : 500,
"b" : 100,
...
"x" : {"a" : 40, "b" : 50},
},
"7": {
"a": 300,
"b": 90,
...
"x": {"a": 4, "b": 5}
}
}
}
{
"pool" : "Foo",
"monthly-figures" : {
"1": {
"a" : 15,
"b" : 25,
...
"x" : {"a" : 20, "b" : 35},
},
"2": {
"a" : 250,
"b" : 200,
...
"x" : {"a" : 60, "b" : 80},
}
}
}
{
"pool" : "Bar",
"monthly-figures" : {
"1": {
"a" : 300,
"b" : 400,
...
"x" : {"a" : 51, "b" : 3},
}
},
"6": {
"a" : 75,
"b" : 135,
...
"x" : {"a" : 12.5, "b" : 16},
}
}
}
我想通过聚合实现的是基于 pool 字段进行分组,然后将 monthly-figures 中包含的值相加 - 所以生成的两个文档看起来像
{
"pool" : "Foo",
"monthly-figures" : {
"1": {
"a" : 25,
"b" : 45,
...
"x" : {"a" : 35, "b" : 65},
},
"2": {
"a" : 750,
"b" : 300,
...
"x" : {"a" : 100, "b" : 130},
},
"7": {
"a": 300,
"b": 90,
...
"x": {"a": 4, "b": 5}
}
}
}
(带有pool 的 Bar 的文档将是相同的,因为只有 1 个)
聚合后一个月是否全为 0 值无关紧要(如果说该月不存在于分组的任何文档中),但理想情况下不存在?
我提出了这个确实有效的查询,但我觉得这不是最好的方法 - 大量重复 - 我该如何改进?
{$group: {
// Group to pool
_id: "$pool",
// Sum grouped documents
"1a": {$sum: "$monthly-figures.1.a"},
"1b": {$sum: "$monthly-figures.1.b"},
...
"1xa": {$sum: "$monthly-figures.1.x.a"},
"1xb": {$sum: "$monthly-figures.1.x.b"},
"2a": {$sum: "$monthly-figures.2.a"},
... Continue all the way down to 12
}
},
{$project: {
"_id": 0,
"pool": "$_id",
"monthly-figures": {
"1": {
"a": "$1a",
"b": "$1b",
...
"x": {
"a": "$1xa",
"b": "$1xb"
}
},
"2": {
"a": "$2a",
...
}
... Continue all the way down to 12
}
}
}
关于更清洁的管道有什么想法吗? 干杯!
【问题讨论】:
标签: mongodb mongodb-query aggregation-framework