PyMongo如何快速查询并拼接所有返回的MyData数组结果
高性能MongoDB查询拼接数组方案
方案1:聚合管道实现服务端直接返回拼接结果(最优)
直接通过MongoDB聚合框架在服务端完成数据过滤、排序、数组合并全流程,无需在Python侧做二次遍历处理,同时减少了无用数据的网络传输,性能远高于客户端遍历方案。
实现代码如下:
from datetime import datetime, timedelta # 聚合管道定义 pipeline = [ # 阶段1:过滤最近10分钟的数据,对应原find的查询条件 {"$match": { "index": { "$lt": datetime.now(), "$gt": datetime.now() - timedelta(minutes=10) } }}, # 阶段2:按index倒序排序,和原逻辑保持一致 {"$sort": {"index": -1}}, # 阶段3:所有符合条件的文档归为一组,收集所有MyData数组 {"$group": { "_id": None, "data_list": {"$push": "$MyData"} }}, # 阶段4:将二维数组展平为一维数组 {"$project": { "_id": 0, "all_data": { "$reduce": { "input": "$data_list", "initialValue": [], "in": {"$concatArrays": ["$$value", "$$this"]} } } }} ] # 执行聚合查询 result = myCollection.aggregate(pipeline, allow_disk_use=True) # 直接获取拼接完成的数组 all_data = list(result)[0]["all_data"]
注意:该方案最终返回的单个文档最大不能超过MongoDB的16MB单文档限制,如果你的拼接后数组总大小超过16MB,使用下方方案2。
方案2:超大结果集适配方案
如果拼接后数组超过16MB,无法用单文档返回,可以保留原find查询逻辑,用Python标准库itertools.chain实现C层面的快速拼接,比手写for循环效率高2~5倍:
from itertools import chain from datetime import datetime, timedelta search_query = {"index" : {"$lt" : datetime.now(), "$gt" : datetime.now() - timedelta(minutes=10)}} filter_query = {"MyData" : 1, "_id" : 0} search_result = myCollection.find(search_query,filter_query).sort("index",-1).allow_disk_use(True) # 快速拼接数组,无需手动循环extend all_data = list(chain.from_iterable(doc["MyData"] for doc in search_result))
性能说明
- 聚合方案适合中小结果集,所有计算在服务端完成,全程只返回最终需要的一维数组,性能最好
- chain方案适合超大结果集,规避了单文档16MB限制,同时比原生Python循环性能高很多
内容的提问来源于stack exchange,提问作者geekygeek
相关产品推荐
相关产品推荐

