Mongo汇总多个组和

时间:2018-08-12 13:47:54

标签: mongodb aggregation-framework

我有一个扁平的数据结构,如下所示:

{
 state: String,
 caseA: Number,
 caseB: Number,
 caseC: Number
}

我想对每个案例进行总计和求和,然后再按状态求每个案例的求和。

我可以做第一部分,但不确定如何进行第二个分组。

{$group: {
 _id: null,
 total_caseA: {$sum: "$caseA"},
 total_caseB: {$sum: "$caseB"},
 total_caseC: {$sum: "$caseC"},
}}

我希望结果看起来像这样:

{
 total_caseA: <sum of all caseA across all states>,
 total_caseB: <sum of all caseB across all states>,
 total_caseC: <sum of all caseB across all states>,
 states: [
  "AK": {
   caseA: <sum of caseA for state>,
   caseB: <sum of caseB for state>,
   caseB: <sum of caseC for state>,
  },
  "CA": {
   caseA: <sum of caseA for state>,
   caseB: <sum of caseB for state>,
   caseB: <sum of caseC for state>,
  },
  ...
 ]
}

谢谢。

1 个答案:

答案 0 :(得分:1)

您可以尝试以下汇总

$facet将为您提供两个不同的数组,一个数组用于total个案例计数,另一个数组用states的{​​{3}}及其案例计数...在状态计数中,您有使用$group ...将所有值推入数组以将值用作键,最后将$arrayToObject与两个数组的第零个元素一起确定输出

db.collection.aggregate([
  { "$facet": {
    "total": [
      { "$group": {
        "_id": null,
        "total_caseA": { "$sum": "$caseA" },
        "total_caseB": { "$sum": "$caseB" },
        "total_caseC": { "$sum": "$caseC" }
      }}
    ],
    "states": [
      { "$group": {
        "_id": "$state",
        "total_caseA": { "$sum": "$caseA" },
        "total_caseB": { "$sum": "$caseB" },
        "total_caseC": { "$sum": "$caseC" }
      }},
      { "$group": {
        "_id": null,
        "data": {
          "$push": {
            "k": "$_id",
            "v": {
              "total_caseA": { "$sum": "$total_caseA" },
              "total_caseB": { "$sum": "$total_caseB" },
              "total_caseC": { "$sum": "$total_caseC" }
            }
          }
        }
      }},
      { "$replaceRoot": { "newRoot": { "$arrayToObject": "$data" } } }
    ]
  }},
  { "$unwind": "$total" },
  { "$addFields": { "total.states": "$states" } },
  { "$project": { "states": 0 } },
  { "$replaceRoot": { "newRoot": "$total" } }
])

输出

[
  {
    "_id": null,
    "states": [
      {
        "AK": {
          "total_caseA": 1,
          "total_caseB": 2,
          "total_caseC": 3
        },
        "CA": {
          "total_caseA": 2,
          "total_caseB": 4,
          "total_caseC": 6
        }
      }
    ],
    "total_caseA": 3,
    "total_caseB": 6,
    "total_caseC": 9
  }
]

$replaceRoot