MongoDB,对复合键元素的嵌套数组上的已过滤元素进行聚合

时间:2015-12-11 16:56:06

标签: mongodb aggregation-framework

问题

我有像这样的元素:

元素1:

{
  "uuid" : "bc972b90-134b-0133-68be-0a81e8b09a82",
  "parent_uuid": "PARENT_UUID_1",
  "demographics" : [ 
    {
      "key" : "country_code",
      "value" : "DE"
    },
    {
      "key" : "gender",
      "value" : "female"
    }
  ]
}

元素2:

{
  "uuid" : "bc972b90-134b-0133-68be-0a81e8b09a83",
  "parent_uuid": "PARENT_UUID_1",
  "demographics" : [ 
    {
      "key" : "country_code",
      "value" : "ES"
    },
    {
      "key" : "gender",
      "value" : "female"
    }
  ]
}

我想计算每个country_code的元素数量,parent_uuid == "PARENT_UUID_1"

由于demographics数组是复合键元素,我不知道如何定义group命令。

我一直在查看$project$unwind等选项,但我不知道它们如何适用于我的示例。

同样this SO Question看起来非常相似,但并不真正符合我的需要,因为我需要进行双重过滤:

  1. 根据parent_id过滤基础数据的元素。
  2. 过滤demographics.key == "country_code"进行自我分组。
  3. 我的方法

    db.getCollection('test').aggregate([
      {
        "$match": {
          "parent_uuid": {
            "$in": [
              "PARENT_UUID_1",
              "PARENT_UUID_2"
            ]
          }
        }
      },
      {
        "$unwind": "$demographics"
      },
      {
        "$group" : {
          "_id" : { 
            "country_code": "$demographics.value"
          },
          "count": { "$sum": 1 }
        }
      }  
    ])
    

    结果:

    {
      "result" : [ 
        {
          "_id" : {
            "country_code" : "ES"
          },
          "count" : 1.0000000000000000
        }, 
        {
          "_id" : {
            "country_code" : "female"
          },
          "count" : 4.0000000000000000
        }, 
        {
          "_id" : {
            "country_code" : "male"
          },
          "count" : 1.0000000000000000
        }, 
        {
          "_id" : {
            "country_code" : "DE"
          },
          "count" : 4.0000000000000000
        }
      ],
      "ok" : 1.0000000000000000
    }
    

    正如预期的那样,查询会弄乱不同的demographics,我只对demographics.key == "country_code"感兴趣。

    问题

    如何定义此聚合?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。

我不知道聚合命令可以连接起来,所以在第一个$match之后,我可以制作$unwind然后另一个$match

db.getCollection('test').aggregate([
  {
    "$match": {
      "parent_uuid": {
        "$in": [
          "PARENT_UUID_1",
          "PARENT_UUID_2"
        ]
      }
    }
  },
  {
    "$unwind": "$demographics"
  },
  {
    "$match": {
      "demographics.key" : "country_code"
    }
  },
  {
    "$group" : {
      "_id" : "$demographics.value",
      "count": { "$sum": 1 }
    }
  },
  {
    "$project" :{
      "_id": 0,
      "country_code": "$_id",
      "count": "$count"
    }
  }     
])

结果:

{
  "result" : [ 
    {
      "count" : 1.0000000000000000,
      "country_code" : "ES"
    }, 
    {
      "count" : 4.0000000000000000,
      "country_code" : "DE"
    }
  ],
  "ok" : 1.0000000000000000
}