MongoDB聚合查询:按用户日期过滤保留success忽略error
MongoDB聚合查询逻辑调整方案
需求概述
需获取指定时间范围内、类型为success或error的用户数据,核心规则:
- 同一用户同一日期同时存在两种类型时,仅保留
success类型 - 仅存在
error类型时,保留error类型 - 同一用户单日多条同类型数据无需去重,只需按日期判断类型优先级
当前查询问题
当前Group阶段将type纳入分组键,导致同一用户同一日期的success和error会被拆分为两个独立分组,不符合需求。
当前Match阶段
{ "$and": [ { "time": { "$gte": ISODate("2023-04-23T00:00:00.000+0000") } }, { "time": { "$lte": ISODate("2023-04-25T00:00:00.000+0000") } }, { "$or": [ { "type": "success" }, { "type": "error" } ] } ] }
当前Group阶段
{ "_id": { "name": "$data.agent.name", "id": "$data.agent.id", "time": { "$dateToString": { "format": "%m-%d-%Y", "date": "$time" } }, "type": "$type" } }
当前返回结果
{ "_id": { "name": "Samus Aran", "id": "ID123456", "time": "04-24-2023", "type": "success" } } { "_id": { "name": "Samus Aran", "id": "ID123456", "time": "04-24-2023", "type": "error" } } { "_id": { "name": "John Doe", "id": "ID654321", "time": "04-24-2023", "type": "error" } } { "_id": { "name": "Jean Moulin", "id": "ID456123", "time": "04-24-2023", "type": "success" } }
调整后的聚合查询
完整聚合管道
[ // 保留原时间与类型过滤逻辑 { "$and": [ { "time": { "$gte": ISODate("2023-04-23T00:00:00.000+0000") } }, { "time": { "$lte": ISODate("2023-04-25T00:00:00.000+0000") } }, { "$or": [ { "type": "success" }, { "type": "error" } ] } ] }, // 第一步分组:按用户+日期聚合,标记是否存在success类型 { "$group": { "_id": { "name": "$data.agent.name", "id": "$data.agent.id", "time": { "$dateToString": { "format": "%m-%d-%Y", "date": "$time" } } }, "hasSuccess": { "$max": { "$cond": [ { "$eq": ["$type", "success"] }, true, false ] } } } }, // 构造最终结果结构:根据标记确定最终type { "$project": { "_id": { "name": "$_id.name", "id": "$_id.id", "time": "$_id.time", "type": { "$cond": [ "$hasSuccess", "success", "error" ] } } } } ]
调整说明
- Group阶段优化:移除
type作为分组键,仅按用户(name+id)和日期分组,通过$max+$cond标记该分组是否存在success类型 - Project阶段补全结构:根据
hasSuccess标记生成最终type,确保同一用户同一日期仅返回一条优先级最高的记录
期望返回结果
{ "_id": { "name": "Samus Aran", "id": "ID123456", "time": "04-24-2023", "type": "success" } } { "_id": { "name": "John Doe", "id": "ID654321", "time": "04-24-2023", "type": "error" } } { "_id": { "name": "Jean Moulin", "id": "ID456123", "time": "04-24-2023", "type": "success" } }
内容的提问来源于stack exchange,提问作者Centdesk67
相关产品推荐
相关产品推荐

