从PyMongo中的字典聚合键/值

时间:2018-11-08 16:21:03

标签: mongodb mongodb-query aggregation-framework

我有一组看起来像这样的文件:

{
  "id": 45,
  "some_list": [{"x": 1, "y": {"a": 10, "b": 32, "c": 91}}, 
                {"x": 2, "y": {"a": 12, "b": 26, "d": 75, "p": 1}}]
}

{
  "id": 119,
  "some_list": [{"x": 1, "y": {"a": 5}}, 
                {"x": 2, "y": {"b": 60, "p": 8}}]
}

我想检索一个汇总了所有y字典的结果。并得到:

{"a": 27, "b": 118, "c": 91, "d": 75, "p": 9}

# a = 10 + 12 + 5
# b = 32 + 26 + 60
# c = 91
# d = 75
# p = 1 + 8

这是我尝试过的:

pipeline = [
    {"$unwind": "$some_list"},
    {"$group": {"_id": "$some_list.y.key", "count": {"$sum": "$some_list.y.value"}}},
]
list(client.db.collection.aggregate(pipeline))

1 个答案:

答案 0 :(得分:0)

您可以使用以下汇总

由于您拥有未知的密钥,因此必须使用$objectToArray将动态密钥转换为kv格式,然后才能轻松地$group它们。

db.collection.aggregate([
  { "$unwind": "$some_list" },
  { "$addFields": {
    "some_list": { "$objectToArray": "$some_list.y" }
  }},
  { "$unwind": "$some_list" },
  { "$group": {
    "_id": "$some_list.k",
    "count": { "$sum": "$some_list.v" }
  }}
])

输出

[
  { "_id": "c", "count": 91 },
  { "_id": "d", "count": 75 },
  { "_id": "p", "count": 9 },
  { "_id": "b", "count": 118 },
  { "_id": "a", "count": 27 }
]

即使您想要键值对中的数据,也可以使用

db.collection.aggregate([
  { "$unwind": "$some_list" },
  { "$addFields": {
    "some_list": { "$objectToArray": "$some_list.y" }
  }},
  { "$unwind": "$some_list" },
  { "$group": {
    "_id": "$some_list.k",
    "count": { "$sum": "$some_list.v" }
  }},
  { "$group": {
    "_id": null,
    "data": { "$push": { "k": "$_id", "v": "$count" }}
  }},
  { "$replaceRoot": { "newRoot": { "$arrayToObject": "$data" }}}
])

输出

[
  {
    "a": 27,
    "b": 118,
    "c": 91,
    "d": 75,
    "p": 9
  }
]