MongoDB中统计ML_PRIORITY的STATUS计数并实现自定义排序
自定义MongoDB聚合结果的ML_PRIORITY排序
问题背景
我有一个名为INFODOCS的集合,包含ML_PRIORITY(可选值:HIGH/MEDIUM/LOW)和STATUS(可选值:True/False/空字符串)字段。需要统计每个ML_PRIORITY对应的各STATUS值的数量,并将结果按HIGH → MEDIUM → LOW的顺序对ML_PRIORITY进行自定义排序。目前已完成统计逻辑,但MongoDB的$sort操作符仅支持升序(1)和降序(-1),不清楚如何实现自定义枚举排序。
集合示例数据
[ { "_id": "1", "ML_PRIORITY" : "HIGH", "STATUS" : "True" }, { "_id": "2", "ML_PRIORITY" : "HIGH", "STATUS" : "" }, { "_id": "3", "ML_PRIORITY" : "HIGH", "STATUS" : "False" }, { "_id": "4", "ML_PRIORITY" : "MEDIUM", "STATUS" : "" }, { "_id": "5", "ML_PRIORITY" : "Low", "STATUS" : "" } ]
现有聚合管道(已完成统计)
db.INFODOCS.aggregate([ { '$group': { '_id': '$ML_PRIORITY', 'QUALITYCHECKDONE': { '$sum': { '$cond': [ { '$eq': [ '$STATUS', 'TRUE' ] }, 1, 0 ] } }, 'QUALITYCHECKNOTDONE': { '$sum': { '$cond': [ { '$eq': [ '$STATUS', '' ] }, 1, 0 ] } }, 'QUALITYCHECKNOTREQ': { '$sum': { '$cond': [ { '$eq': [ '$STATUS', 'FALSE' ] }, 1, 0 ] } } } }, { '$project': { '_id': 0, 'ML_PRIORITY': '$_id', 'QUALITYCHECKDONE': 1, 'QUALITYCHECKNOTDONE': 1, 'QUALITYCHECKNOTREQ': 1 } } ])
解决方案:添加排序权重实现自定义排序
核心思路是为每个ML_PRIORITY映射一个数值权重,再按权重升序排序,就能得到指定的顺序。同时建议先统一ML_PRIORITY的大小写,避免因大小写差异导致分组错误(比如示例中的"Low"和"LOW")。
修改后的完整聚合管道
db.INFODOCS.aggregate([ // 统一ML_PRIORITY的大小写,避免分组错误 { '$addFields': { 'normalized_priority': { '$toUpper': '$ML_PRIORITY' } } }, // 按统一后的优先级分组统计 { '$group': { '_id': '$normalized_priority', 'QUALITYCHECKDONE': { '$sum': { '$cond': [ // 忽略STATUS的大小写差异,避免统计遗漏 { '$eq': [ { '$toUpper': '$STATUS' }, 'TRUE' ] }, 1, 0 ] } }, 'QUALITYCHECKNOTDONE': { '$sum': { '$cond': [ { '$eq': [ '$STATUS', '' ] }, 1, 0 ] } }, 'QUALITYCHECKNOTREQ': { '$sum': { '$cond': [ { '$eq': [ { '$toUpper': '$STATUS' }, 'FALSE' ] }, 1, 0 ] } } } }, // 添加排序权重字段,映射自定义顺序 { '$addFields': { 'sort_order': { '$switch': { 'branches': [ { 'case': { '$eq': [ '$_id', 'HIGH' ] }, 'then': 1 }, { 'case': { '$eq': [ '$_id', 'MEDIUM' ] }, 'then': 2 }, { 'case': { '$eq': [ '$_id', 'LOW' ] }, 'then': 3 } ], 'default': 4 // 未知优先级默认放在最后 } } } }, // 按权重升序排序,得到HIGH→MEDIUM→LOW的顺序 { '$sort': { 'sort_order': 1 } }, // 调整输出字段,移除权重字段保持结果整洁 { '$project': { '_id': 0, 'ML_PRIORITY': '$_id', 'QUALITYCHECKDONE': 1, 'QUALITYCHECKNOTDONE': 1, 'QUALITYCHECKNOTREQ': 1 } } ])
关键步骤说明
- 统一大小写:用
$toUpper将ML_PRIORITY转换为大写,确保不同大小写的同一优先级被归为一组。 - 映射排序权重:通过
$switch为每个优先级分配对应数值,HIGH=1、MEDIUM=2、LOW=3,按此数值升序排序即可得到自定义顺序。 - 优化STATUS判断:同样用
$toUpper统一STATUS的大小写,避免因"True"和"TRUE"这类差异导致统计错误。 - 清理输出字段:排序完成后移除临时的
sort_order字段,保持结果结构与原需求一致。
输出结果示例
[ { "QUALITYCHECKDONE": 1, "QUALITYCHECKNOTDONE": 1, "QUALITYCHECKNOTREQ": 1, "ML_PRIORITY": "HIGH" }, { "QUALITYCHECKDONE": 0, "QUALITYCHECKNOTDONE": 1, "QUALITYCHECKNOTREQ": 0, "ML_PRIORITY": "MEDIUM" }, { "QUALITYCHECKDONE": 0, "QUALITYCHECKNOTDONE": 1, "QUALITYCHECKNOTREQ": 0, "ML_PRIORITY": "LOW" } ]
内容的提问来源于stack exchange,提问作者ankit lohiya
相关产品推荐
相关产品推荐

