PyMongo查询文档对象属性数量及$objectToArray报错解决
MongoDB对象属性数量统计及报错修复
需求说明
需要从数百个如下结构的MongoDB文档中,统计Notes和BehavioralData对象的属性数量:
{"_id": "123","Notes": {"1222": "Something is here"},"BehavioralData": {"Folder1": {"Sex": "Male","Age": "22","Date": "","ResearchGroup": "","Institution": "University of Manitoba"},"MoCA": {"Visual-Executive": "","Naming": "NameHere","Attention": "","Language": "","Abstraction": "","Delayed Recall": "","Orientation": "","Education": "","Total": ""}}}
期望输出格式:
{"NotesLength": 1,"BehavioralLength": 2}
报错原因
执行聚合时出现Location17124错误,核心原因是部分文档中Notes或BehavioralData字段为null或不存在,使用$objectToArray转换后得到null值,而$size运算符要求输入必须是数组,无法处理null类型。
解决方案
1. MongoDB聚合命令
通过$ifNull将可能为null或不存在的字段转换为空对象,再用$objectToArray把对象转为键值对数组,最后通过$size统计数组长度:
db.collection.aggregate([ { $project: { NotesLength: { $size: { $objectToArray: { $ifNull: ["$Notes", {}] } } }, BehavioralLength: { $size: { $objectToArray: { $ifNull: ["$BehavioralData", {}] } } } } }, // 如需统计所有文档的属性数量总和,保留以下阶段;仅需单文档统计则删除 { $group: { _id: null, totalNotesLength: { $sum: "$NotesLength" }, totalBehavioralLength: { $sum: "$BehavioralLength" } } } ])
2. PyMongo实现代码
结合PyMongo执行上述聚合逻辑,兼容字段为null或不存在的场景:
from pymongo import MongoClient # 连接MongoDB client = MongoClient("mongodb://localhost:27017/") db = client["your_database_name"] collection = db["your_collection_name"] # 单文档属性数量统计(取第一个匹配文档) single_doc_stats = collection.aggregate([ { "$match": {} }, # 可添加过滤条件缩小范围 { "$project": { "NotesLength": { "$size": { "$objectToArray": { "$ifNull": ["$Notes", {}] } } }, "BehavioralLength": { "$size": { "$objectToArray": { "$ifNull": ["$BehavioralData", {}] } } } } }, { "$limit": 1 } ]).next() print("单文档统计结果:", single_doc_stats) # 所有文档属性数量累计统计 total_stats = collection.aggregate([ { "$project": { "NotesLength": { "$size": { "$objectToArray": { "$ifNull": ["$Notes", {}] } } }, "BehavioralLength": { "$size": { "$objectToArray": { "$ifNull": ["$BehavioralData", {}] } } } } }, { "$group": { "_id": None, "totalNotesLength": { "$sum": "$NotesLength" }, "totalBehavioralLength": { "$sum": "$BehavioralLength" } } } ]).next() print("累计统计结果:", total_stats)
内容的提问来源于stack exchange,提问作者Alisher Myrgyyassov
相关产品推荐
相关产品推荐

