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

时间:2015-04-26 15:48:36

标签: 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
                    }
                 ]
              }
           ]
        }
      ]
   }
 ]
}

我在寻找什么

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

  1. eventName的
  2. 网站名称
  3. 因此,对于我希望得到的文件:

    1. 组合{“Party”,“After Party”,“club8”}总和40
    2. 组合{“Party”,“After Party”,“PostParty”}总和90
    3. 我尝试了什么

      我尝试将聚合运算符与_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' }
      }
      });
      

      结果

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

       {
         "_id":{
            "type":[
               "Party"
            ],
            "name":[
               [
                  "After Party"
               ]
            ],
            "siteName":[
               [
                  [
                     "club8",
                     "PostParty"
                  ]
               ]
            ]
         },
         "total":0
      }
      

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

1 个答案:

答案 0 :(得分:11)

您需要先在所有阵列上应用$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
        }
    }
]);

<强>输出

/* 1 */
{
    "result" : [ 
        {
            "total" : 90,
            "type" : "Party",
            "name" : "After Party",
            "siteName" : "PostParty"
        }, 
        {
            "total" : 40,
            "type" : "Party",
            "name" : "After Party",
            "siteName" : "club8"
        }
    ],
    "ok" : 1
}