MongoDB - 使用嵌套字段对复合键进行分组

ass*_*afm 10 mongodb

我在mongodb中有这个文件:

{
"_id":"26/04/2015 09:50",
"reservations":130,
"Event_types":[
   {
     "type":"Party",
     "events":[
        {
           "eventName":"After Party",
           "total_count":130,
           "by":[
              {
                 "siteName":"club8",
                 "countArray":[
                    {
                       "bucket":"default",
                       "value":40
                    }
                 ]
              },
              {
                 "siteName":"PostParty",
                 "countArray":[
                    {
                       "bucket":"1",
                       "value":70
                    },
                    {
                       "bucket":"2",
                       "value":20
                    }
                 ]
              }
           ]
        }
      ]
   }
 ]
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找什么

我希望通过以下字段对"值"字段和组进行求和:

  1. 类型
  2. eventName的
  3. 网站名

所以对于我希望得到的文件:

  1. 对于组合{"Party","After Party","club8"}总和为40
  2. 对于组合{"Party","After Party","PostParty"}总和为90

我试过的

我已经尝试使用聚合运算符和_id的复合键:

db.testing.aggregate(
{ 
$group : {
    _id : 
    {
    type:'$Event_types.type',
    name: '$Event_types.events.eventName',
    siteName: '$Event_types.events.by.siteName'
    }
    , total : { $sum : '$Event_types.events.by.countArray.value' }
}
});
Run Code Online (Sandbox Code Playgroud)

结果

一个文档,有3个数组 - 每个我希望分组的值."siteName"数组包含"siteName"可用的2个值."总数"似乎没有总结任何东西,它只出现一次 - 我希望在文档中的每个"SiteName"值旁边看到它.

 {
   "_id":{
      "type":[
         "Party"
      ],
      "name":[
         [
            "After Party"
         ]
      ],
      "siteName":[
         [
            [
               "club8",
               "PostParty"
            ]
         ]
      ]
   },
   "total":0
}
Run Code Online (Sandbox Code Playgroud)

我是以错误的方式使用"聚合"还是我使用的架构不适合我的目标?谢谢.

chr*_*dam 12

您需要首先$unwind在所有阵列上应用运算符,以便$group稍后在管道阶段与运算符进行聚合计算.最后,您将得到一个像这样的聚合管道:

db.testing.aggregate([
    { "$unwind": "$Event_types" },
    { "$unwind": "$Event_types.events" },
    { "$unwind": "$Event_types.events.by" },
    { "$unwind": "$Event_types.events.by.countArray" },
    {
        "$group": {
            "_id": {
                "type": "$Event_types.type",
                "name": "$Event_types.events.eventName",
                "siteName": "$Event_types.events.by.siteName"
            },
            "total": { 
                "$sum": "$Event_types.events.by.countArray.value"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "type": "$_id.type",
            "name": "$_id.name",
            "siteName": "$_id.siteName",
            "total": 1
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

产量

/* 1 */
{
    "result" : [ 
        {
            "total" : 90,
            "type" : "Party",
            "name" : "After Party",
            "siteName" : "PostParty"
        }, 
        {
            "total" : 40,
            "type" : "Party",
            "name" : "After Party",
            "siteName" : "club8"
        }
    ],
    "ok" : 1
}
Run Code Online (Sandbox Code Playgroud)