display单个mongo查询中多个键的计数

时间:2015-09-30 12:22:29

标签: mongodb mongodb-query aggregation-framework

我有一个mongo集合,其中包含以下类型的数据:

{ "_id" : ObjectId("55d5b739f067897648000007"), "did" : "deviceA","key" : "key1"}

我需要计算设备出现的每个密钥的数量。我写了以下聚合查询:

db.my_collection.aggregate([{'$group':{'_id':{'deviceid':"$did",'keyis':"$key"},'count':{'$sum':1}}}])

我得到以下结果:

{ "_id" : { "deviceid" : "deviceA", "keyis" : "key1" }, "count" : 1 }
{ "_id" : { "deviceid" : "deviceA", "keyis" : "key2" }, "count" : 3 }
{ "_id" : { "deviceid" : "deviceB", "keyis" : "key1" }, "count" : 1 }
{ "_id" : { "deviceid" : "deviceB", "keyis" : "key3" }, "count" : 1 }
{ "_id" : { "deviceid" : "deviceB", "keyis" : "key4" }, "count" : 1 }
{ "_id" : { "deviceid" : "deviceC", "keyis" : "key2" }, "count" : 1 }
{ "_id" : { "deviceid" : "deviceC", "keyis" : "key3" }, "count" : 2 }

想要的东西是这样的:

{ "_id" : { "deviceid" : "deviceA"}, "count_key1" : 1, "count_key2": 3, "count_key3": 0, "count_key4": 0 }
{ "_id" : { "deviceid" : "deviceB"}, "count_key1" : 1, "count_key2": 0, "count_key3": 1, "count_key4": 1 }
{ "_id" : { "deviceid" : "deviceC"}, "count_key1" : 0, "count_key2": 1, "count_key3": 2, "count_key4": 0 }

是否可以在单个mongo查询中执行??

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

您可以简单地将$sum$cond一起用于聚合:

db.collection.aggregate({
  "$group": {
    "_id": {
      "deviceid": "$did"
    },
    "count_key1": {
      "$sum": {
        "$cond": {
          "if": {
            "$eq": ["$key", "key1"]
          },
          "then": 1,
          "else": 0
        }
      }
    },
    "count_key2": {
      "$sum": {
        "$cond": {
          "if": {
            "$eq": ["$key", "key2"]
          },
          "then": 1,
          "else": 0
        }
      }
    },
    "count_key3": {
      "$sum": {
        "$cond": {
          "if": {
            "$eq": ["$key", "key3"]
          },
          "then": 1,
          "else": 0
        }
      }
    },
    "count_key4": {
      "$sum": {
        "$cond": {
          "if": {
            "$eq": ["$key", "key4"]
          },
          "then": 1,
          "else": 0
        }
      }
    }
  }
})

答案 1 :(得分:1)

没有直接的方法可以做到这一点。但我们可以解决这个问题。

我创建了一小部分数据,就像你的一样(抱歉格式不正确):

 > db.q.find()
   { "_id" : ObjectId("55d5b739f067897648000007"), "did" : "deviceA", "key" : "key1" }
   { "_id" : ObjectId("55d5b739f067897648000008"), "did" : "deviceB", "key" : "key1" }
   { "_id" : ObjectId("55d5b739f067897648000009"), "did" : "deviceB", "key" : "key2" }
   { "_id" : ObjectId("55d5b739f067897648000019"), "did" : "deviceA", "key" : "key2" }
   { "_id" : ObjectId("55d5b739f067897648000201"), "did" : "deviceA", "key" : "key2" }

以下查询将给出您想要的结果:

db.q.aggregate([{
'$group':{'_id':{'deviceid':"$did",'keyis':"$key"},
'count':{'$sum':1}}},{'$group':{'_id':{'deviceid':'$_id.deviceid'},
'counts':{'$push':{'name':'$_id.keyis','count':'$count'}}}},
{'$unwind':'$counts'},{
"$project" : {
    "countKey1" : {
        "$cond" : [
            {
                "$eq" : [
                    "key1",
                    "$counts.name"
                ]
            },
            "$counts.count",
            0
        ]
    },"countKey2" : {
        "$cond" : [
            {
                "$eq" : [
                    "key2",
                    "$counts.name"
                ]
            },
            "$counts.count",
            0
        ]
    }}},{
"$group" : {
    "_id" : "$_id",
    "countKey1" : {
        "$max" : "$countKey1"
    },
    "countKey2" : {
        "$max" : "$countKey2"
    }
}
}])

//结果:

{ "_id" : { "deviceid" : "deviceA" }, "countKey1" : 1, "countKey2" : 2 }
{ "_id" : { "deviceid" : "deviceB" }, "countKey1" : 1, "countKey2" : 1 }

在这里,我假设您在编写查询时知道有一组有限的键和值。

有关详情:Blog post on dynamic field names by Asya