如何用PyMongo无需循环统计Python列表元素对应MongoDB文档数及总数
PyMongo 批量统计最优实现方案
你可以直接使用MongoDB的聚合查询完成需求,全程仅需和数据库交互1次,完全不需要循环发起多次查询,性能远高于逐次查询的实现。
完整实现代码(同时满足两项统计需求)
from pymongo import MongoClient # 假设你已经初始化好db对象 my_list = ["a", "b", "c"] # 聚合查询管道 pipeline = [ # 第一步:过滤仅保留item在目标列表中的文档,缩小计算范围 {"$match": {"item": {"$in": my_list}}}, # 第二步:按item分组统计每个元素的文档数,同时累加总数量 {"$group": { "_id": "$item", "item_count": {"$sum": 1} }}, # 第三步:合并结果,计算总匹配数同时整理各元素的统计结果 {"$group": { "_id": None, "per_item_stats": {"$push": {"item": "$_id", "count": "$item_count"}}, "total_match_count": {"$sum": "$item_count"} }} ] # 执行查询 result = list(db.collection.aggregate(pipeline)) # 提取结果 if result: # 每个元素对应的文档数量 per_item_count = {i["item"]:i["count"] for i in result[0]["per_item_stats"]} # 所有匹配文档总数量 total = result[0]["total_match_count"] # 补全列表中没有匹配到的元素的统计(数量为0) for item in my_list: if item not in per_item_count: per_item_count[item] = 0
可选的分场景简化实现
如果不需要同时获取两个统计结果,可以拆分为更简单的查询:
- 单独统计每个元素对应文档数量
pipeline = [ {"$match": {"item": {"$in": my_list}}}, {"$group": {"_id": "$item", "count": {"$sum": 1}}} ] per_item_count = {x["_id"]:x["count"] for x in db.collection.aggregate(pipeline)} - 单独统计所有匹配文档总数量
直接使用$in操作符批量查询,不需要循环:total = db.collection.count_documents({"item": {"$in": my_list}})
注意:如果你的列表元素数量极多(超过1000个),可以考虑拆分批次查询,避免单次请求数据量过大。
内容的提问来源于stack exchange,提问作者Alex Dana
相关产品推荐
相关产品推荐

