MongoDB聚合查询如何输出计数为0的空字段并正确格式化返回结果
完整聚合查询语句
[ // 展开sessions数组 {$unwind: "$sessions"}, // 展开sessions下的actions数组 {$unwind: { path: "$sessions.actions" }}, // 按用户编号+操作类型分组,统计次数和最晚操作时间 {$group: { "_id": { "number": "$number", "type": "$sessions.actions.type" }, "last": {"$max": "$sessions.actions.created"}, "count": {"$sum": 1} }}, // 按用户编号分组,汇总同用户的所有操作统计 {$group: { "_id": "$_id.number", "existActions": {"$push": {"type": "$_id.type", "last": "$last", "count": "$count"}} }}, // 补全所有4种操作类型,缺失的默认count为0、last为null {$addFields: { "allActionTypes": [ {"type": "create", "last": null, "count": 0}, {"type": "read", "last": null, "count": 0}, {"type": "update", "last": null, "count": 0}, {"type": "delete", "last": null, "count": 0} ], "number": "$_id" }}, // 合并已有统计和全量类型列表,去重取实际值 {$project: { "_id": 0, "number": 1, "actions": { "$map": { "input": "$allActionTypes", "as": "baseType", "in": { "$let": { "vars": { "matchAction": { "$first": { "$filter": { "input": "$existActions", "cond": {"$eq": ["$$this.type", "$$baseType.type"]} } } } }, "in": { "type": "$$baseType.type", "last": {"$ifNull": ["$$matchAction.last", null]}, "count": {"$ifNull": ["$$matchAction.count", 0]} } } } } } }} ]
关键逻辑说明
- 原有查询仅返回存在操作记录的类型,新增的
$addFields步骤定义了所有需要返回的4种操作类型的默认值,确保缺失的类型也能出现在结果中 - 最后的
$project步骤通过$map+$filter组合,把已有的统计结果覆盖到默认类型列表上,没有匹配到的类型就保留默认的count:0和last:null - 你给出的预期返回格式存在语法笔误:
'last': 'created': ISODate('2020-01-01T01:33:59')多了一层created键,上述查询返回的last字段直接对应操作时间,符合正常语法规范
内容的提问来源于stack exchange,提问作者sainekk
相关产品推荐
相关产品推荐

