以下是文档示例,年份字段包含年份密钥,其中包含一些包含天数作为键的指标:
{
"_id" : NumberInt(1),
"year" : {
"2017" : {
"g1" : {
"1" : {
"total" : 2.0
},
"2" : {
"total" : 5.0
}
},
"g2" : {
"1" : {
"total" : 3.0
},
"2" : {
"total" : 6.0
}
}
}
}
我不希望将文档存入内存以总结每个关键字段g#的总字段。
我怎么能对mongodb说,为年份字段中的每个键汇总总字段。
我想要的结果:g1 = 7.0,g2 = 9.0
答案 0 :(得分:1)
您必须将结构的year
部分更改为以下内容。(首选)
"year" : [{ "k" : "2017", "v":[{ "k": "g1", "v":[{ "k" : "1","v" : {"total" : 2 }},{ "k" : "2","v" : {"total" : 5}}]}, { "k": "g2", "v":[{ "k" : "1","v" : {"total" : 3 }},{ "k" : "2","v" : {"total" : 6}}]}]}]
您可以进行以下聚合。这将在不事先知道密钥的情况下工作。
查询$unwinds
几次到达g & total
文档后跟g
项上的组,并计算total
总和。
db.collection.aggregate([
{$match:{_id:1}},
{$unwind:"$year"},
{$unwind:"$year.v"},
{$unwind:"$year.v.v"},
{
$group:
{
_id:"$year.v.k",
sum: {$sum:"$year.v.v.v.total"}
}
}
])
如果您无法改变结构,这就是解决方案。
您可以使用3.4.4
版本并使用$objectToArray
将所有动态密钥转换为带标签的密钥和值对。
第1阶段& 2:匹配_id
过滤器并将动态year
密钥转换为标签值对。
第3阶段& 4:$ unwind year
阵列&在将total
和g1
动态键更改为标记为键和值对之前,$减少g2
值以计算总和。
db.collection.aggregate([
{$match:{_id:1}},
{$addFields: {"year": {$objectToArray: "$year"}}},
{$unwind:"$year"},
{
$project:
{
g1:
{
$reduce: {
input: {$objectToArray: "$year.v.g1"},
initialValue: 0,
in: { $sum: [ "$$value", "$$this.v.total" ] }
}
},
g2:
{
$reduce: {
input: {$objectToArray: "$year.v.g2"},
initialValue: 0,
in: { $sum: [ "$$value", "$$this.v.total" ] }
}
}
}
}
])