我有一组看起来像这样的文件:
{
"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))
答案 0 :(得分:0)
您可以使用以下汇总
由于您拥有未知的密钥,因此必须使用$objectToArray
将动态密钥转换为k
和v
格式,然后才能轻松地$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
}
]