首页 文章

PyMongo中字典的聚合键/值

提问于
浏览
1

我有一组文件看起来像:

{
  "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

    您可以使用以下聚合

    由于你有未知的密钥,你必须使用$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
      }
    ]
    

相关问题