如何用Python(PyMongo)计算MongoDB中嵌套字段的跨文档总和
按游戏类型统计获胜总数的PyMongo聚合查询
你的问题核心是需要把嵌套文档中的键(如football、basketball)转换为可聚合的值,MongoDB的$objectToArray操作符可以帮你实现这一点,结合聚合管道的其他阶段就能完成统计。
以下是针对你的文档结构的完整PyMongo代码:
from pymongo import MongoClient client = MongoClient() db = client.your_database_name collection = db.your_collection_name pipeline = [ # 将wins.texas下的游戏键值对转为数组,每个元素是{k: 游戏类型, v: 获胜数据} { "$addFields": { "games": {"$objectToArray": "$wins.texas"} } }, # 展开数组,每个游戏类型单独成为一个文档 {"$unwind": "$games"}, # 分组统计每个游戏类型的总获胜数,根据不同游戏的字段取对应值 { "$group": { "_id": "$games.k", "total_wins": { "$sum": { "$cond": [ {"$eq": ["$games.k", "football"]}, "$games.v.count", "$games.v.open_count" ] } } } } ] result = list(collection.aggregate(pipeline)) print(result)
代码说明
- $objectToArray:把
wins.texas这个嵌套文档转换成[{k: "football", v: {count:1}}, {k: "basketball", v: {open_count:1}}]这样的数组,让原本的键(游戏类型)变成可处理的字段。 - $unwind:将数组展开,每个游戏类型对应一条独立的文档,方便后续分组。
- $group:以游戏类型(
$games.k)为分组键,用$sum计算总数。这里用$cond判断游戏类型,分别取count或open_count的值求和,适配你文档里不同游戏的字段差异。
如果你的文档中还有其他州(比如除了texas还有其他州的游戏数据),可以把$objectToArray的目标改成$wins,再多一层$unwind来处理州的维度,调整后的管道如下:
pipeline = [ {"$addFields": {"states": {"$objectToArray": "$wins"}}}, {"$unwind": "$states"}, {"$addFields": {"games": {"$objectToArray": "$states.v"}}}, {"$unwind": "$games"}, { "$group": { "_id": "$games.k", "total_wins": { "$sum": { "$cond": [ {"$eq": ["$games.k", "football"]}, "$games.v.count", "$games.v.open_count" ] } } } } ]
运行第一个管道后,针对你给出的两个文档,会得到如下结果:
[{'_id': 'football', 'total_wins': 4}, {'_id': 'basketball', 'total_wins': 5}]
内容的提问来源于stack exchange,提问作者iCrus
相关产品推荐
相关产品推荐

