Mongo聚合查询:找出用户集合中含无效组ID的文档
MongoDB聚合查询:找出含无效Group ID的用户文档
核心需求
找出users集合中,groups._id不存在于groups集合的文档。
方案一:纯聚合查询(无需提前加载数据)
db.users.aggregate([ // 关联groups集合,匹配出用户所有存在的group记录 { $lookup: { from: "groups", localField: "groups._id", foreignField: "_id", as: "matched_valid_groups" } }, // 提取有效group的_id数组 { $addFields: { valid_group_ids: { $map: { input: "$matched_valid_groups", as: "g", in: "$$g._id" } } } }, // 筛选出存在无效group的用户 { $match: { $expr: { $gt: [ { $size: { $filter: { input: "$groups", as: "user_group", cond: { $not: { $in: [ "$$user_group._id", "$valid_group_ids" ] } } } } }, 0 ] } } }, // 清理临时字段(可选) { $project: { matched_valid_groups: 0, valid_group_ids: 0 } } ])
各阶段说明
- $lookup:将用户的每个
groups._id与groups集合匹配,把存在的group数据存入matched_valid_groups - $addFields:从匹配结果中提取所有有效的group _id,生成
valid_group_ids数组 - $match:通过
$filter筛选用户groups中不在valid_group_ids里的元素,只要筛选结果长度>0,说明该用户存在无效group,保留该文档 - $project:移除聚合过程中生成的临时字段,返回用户原结构数据
方案二:预加载有效ID(性能更优,适合groups数据量小的场景)
先获取groups集合所有有效_id,再直接查询users:
// 第一步:获取所有有效group的_id数组 const validGroupIds = db.groups.find({}, { _id: 1 }).map(doc => doc._id); // 第二步:查询含无效group的用户 db.users.find({ $expr: { $gt: [ { $size: { $filter: { input: "$groups", as: "g", cond: { $not: { $in: [ "$$g._id", validGroupIds ] } } } } }, 0 ] } })
这种方式避免了聚合中的关联操作,直接在内存中完成有效ID的匹配,查询效率更高。
内容的提问来源于stack exchange,提问作者user23467510
相关产品推荐
相关产品推荐

