MongoDB中如何统计字段唯一值数量?求更优实现方案
MongoDB聚合优化:统计唯一PROCESSOR_ID的两类指标
需求回顾
给定INFODOCS集合,包含PROCESSOR_ID和STATUS字段(STATUS可取"True"、"False"或空字符串),需要统计:
- Working_Processor:存在非空
STATUS的唯一PROCESSOR_ID数量 - Total_Processor:所有唯一
PROCESSOR_ID的数量
示例数据
[ { "_id": "1", "PROCESSOR_ID": "11", "STATUS": "True" }, { "_id": "2", "PROCESSOR_ID": "11", "STATUS": "" }, { "_id": "3", "PROCESSOR_ID": "22", "STATUS": "False" }, { "_id": "4", "PROCESSOR_ID": "33", "STATUS": "" } ]
预期结果
Working_Processor = 2,Total_Processor = 3
当前实现的问题
你当前使用$addToSet结合$cond的方案存在两个明显缺陷:
- 会将
None混入WORKING_PROCESSOR集合,需手动减1修正,逻辑冗余且不直观 - 当没有符合条件的处理器时,
$size -1会得到负数结果,存在边界错误
更优实现方案
方案一:分阶段分组统计(推荐)
先按PROCESSOR_ID分组,标记每个处理器是否有非空STATUS,再全局统计总数和有效数,逻辑清晰且性能更优:
[ // 按PROCESSOR_ID分组,标记是否存在非空STATUS { "$group": { "_id": "$PROCESSOR_ID", "is_working": { "$max": { "$ne": ["$STATUS", ""] } } } }, // 全局统计总数和有效数 { "$group": { "_id": null, "Total_Processor": { "$sum": 1 }, "Working_Processor": { "$sum": { "$cond": ["$is_working", 1, 0] } } } }, // 格式化输出字段 { "$project": { "_id": 0, "Total_Processor": 1, "Working_Processor": 1 } } ]
优势:
- 逻辑直观:先确认每个处理器的有效状态,再统计数量,无额外修正步骤
- 无边界错误:即使没有有效处理器,
Working_Processor会正确返回0 - 性能更好:避免了大集合上的
$addToSet操作($addToSet在数据量大时内存开销高)
方案二:用$filter替代手动减1
如果偏好单阶段分组的结构,可使用$filter过滤空值,避免手动修正的隐患:
[ { "$group": { "_id": null, "all_processors": { "$addToSet": "$PROCESSOR_ID" }, "working_candidates": { "$addToSet": { "$cond": [{ "$ne": ["$STATUS", ""] }, "$PROCESSOR_ID", ""] } } } }, { "$project": { "_id": 0, "Total_Processor": { "$size": "$all_processors" }, "Working_Processor": { "$size": { "$filter": { "input": "$working_candidates", "cond": { "$ne": ["$$this", ""] } } } } } } ]
优势:保留了单阶段分组的结构,但用$filter替代手动减1,逻辑更安全,不会出现负数结果。
内容的提问来源于stack exchange,提问作者ankit lohiya
相关产品推荐
相关产品推荐

