MongoDB聚合结果过滤:基于PID匹配Job状态筛选用户及PID
需求说明
现有聚合查询输出的嵌套数据结构,根层级的pid与用户jobs数组中的id对应,需要完成以下过滤:
- 过滤掉**存在
job.id等于当前pid且job.status不为"Active"**的用户; - 移除过滤后
user数组为空的根条目。
原始数据示例
[ { "pid":"123", "title":"title1", "user" :[ { "id":"user1", "title":"title1 user1", "jobs":[ {"id":"123","status" :"Active"}, {"id":"456","status" :"Active"} ] }, { "id":"user2", "title":"title1 user2", "jobs":[ {"id":"123","status" :"Inactive"}, {"id":"456","status" :"Active"} ] } ] }, { "pid":"456", "title":"title1", "user" :[ { "id":"user1", "title":"title1 user1", "jobs":[ {"id":"123","status" :"Active"}, {"id":"456","status" :"Inactive"} ] }, { "id":"user2", "title":"title1 user2", "jobs":[ {"id":"123","status" :"Inactive"}, {"id":"456","status" :"Inactive"} ] } ] }, { "pid":"789", "title":"title1", "user" :[ { "id":"user1", "title":"title1 user1", "jobs":[ {"id":"789","status" :"Active"}, {"id":"456","status" :"Inactive"} ] }, { "id":"user2", "title":"title1 user2", "jobs":[ {"id":"789","status" :"Active"}, {"id":"456","status" :"Inactive"} ] } ] } ]
期望输出示例
[ { "pid":"123", "title":"title1", "user" :[ { "id":"user1", "title":"title1 user1", "jobs":[ {"id":"123","status" :"Active"}, {"id":"456","status" :"Active"} ] } ] }, { "pid":"789", "title":"title1", "user" :[ { "id":"user1", "title":"title1 user1", "jobs":[ {"id":"789","status" :"Active"}, {"id":"456","status" :"Inactive"} ] }, { "id":"user2", "title":"title1 user2", "jobs":[ {"id":"789","status" :"Active"}, {"id":"456","status" :"Inactive"} ] } ] } ]
解决方案(MongoDB聚合管道实现)
结合$addFields、$filter和$match操作符完成需求,具体聚合管道如下:
db.collection.aggregate([ // 第一步:过滤每个根条目下的user数组,保留符合条件的用户 { $addFields: { user: { $filter: { input: "$user", as: "u", cond: { $let: { vars: { targetJob: { $first: { $filter: { input: "$$u.jobs", as: "j", cond: { $eq: ["$$j.id", "$pid"] } } } } }, in: { $eq: ["$$targetJob.status", "Active"] } } } } } } }, // 第二步:过滤掉user数组为空的根条目 { $match: { $expr: { $gt: [{ $size: "$user" }, 0] } } } ])
步骤解释
- $addFields + $filter:遍历每个根条目的
user数组,对每个用户:- 先筛选出该用户
jobs中id等于当前根条目pid的job(用$first取唯一匹配项); - 判断该job的
status是否为"Active",符合条件的用户保留在user数组中。
- 先筛选出该用户
- $match:过滤掉
user数组长度为0的根条目,确保最终结果只保留有有效用户的条目。
内容的提问来源于stack exchange,提问作者user2842284
相关产品推荐
相关产品推荐

