MongoDB聚合查询需求:关联任务与有效动作并过滤结果
解决Task关联Action的聚合查询需求
需求明确
需要查询满足以下全部条件的任务:
- 任务自身的
active字段为true - 关联的Action中至少有一个
active字段为true - 无符合条件关联动作的任务不返回
原查询的问题分析
你当前的聚合查询能实现基本过滤,但存在两个可优化的点:
- 先执行
$lookup再过滤任务,会先拉取所有任务的关联动作,再过滤符合条件的任务,数据处理量更大,效率偏低 - 返回的
actions数组会包含所有关联动作(包括active: false的),如果只需要保留有效动作,结果不符合预期
优化后的聚合查询
下面的写法更高效,且能精准返回符合需求的数据:
const tasks = await Task.aggregate([ // 第一步:先过滤出自身符合条件的任务,减少后续关联的数据量 { $match: { group: new mongoose.Types.ObjectId(groupId), active: true } }, // 第二步:关联查询时直接过滤出active为true的Action { $lookup: { from: "actions", localField: "_id", foreignField: "task", as: "actions", pipeline: [ { $match: { active: true } } ] } }, // 第三步:过滤掉没有有效关联动作的任务 { $match: { "actions.0": { $exists: true } } } ]).exec();
代码说明
- 前置任务过滤:先通过
$match筛选出group匹配且active: true的任务,避免对无效任务执行关联操作 - 精准关联查询:利用
$lookup的pipeline参数,在关联查询阶段就只获取active: true的Action,减少数据传输和处理 - 过滤空关联任务:通过
"actions.0": { $exists: true }确保返回的任务至少有一个符合条件的关联动作
如果你的需求允许保留所有关联动作(即使包含active: false的),仅需要确保任务存在有效动作,也可以在原查询基础上添加$match: { "actions.0": { $exists: true } }来排除无有效动作的任务,但效率仍不如优化后的写法。
内容的提问来源于stack exchange,提问作者24sharon
相关产品推荐
相关产品推荐

