如何修改MongoDB聚合查询以正确筛选用户abc的合作伙伴建议
问题:修正MongoDB聚合查询以保留rrr为合作伙伴建议
需求说明
- 为用户abc筛选新合作伙伴建议
- 排除abc已主动发送请求的用户123
- 保留向abc发送请求的用户rrr(abc未向rrr发起过请求,符合建议条件)
现有集合
1. User集合
[ { _id: "abc", name: "abc", group: 1 }, { _id: "xyz", name: "xyyy", group: 1 }, { _id: "123", name: "yyy", group: 1 }, { _id: "rrr", name: "tttt", group: 1 }, { _id: "eee", name: "uuu", group: 1 } ]
2. Partnership集合(合作请求记录)
[ { _id: "abc_123", fromUser: "abc", toUser: "123" }, { _id: "rrr_abc", fromUser: "rrr", toUser: "abc" }, { _id: "xyz_rrr", fromUser: "xyz", toUser: "rrr" } ]
当前错误查询
现有聚合查询错误排除了rrr,代码如下:
db.users.aggregate([ { $match: { group: 1, _id: { $ne: "abc" } } }, { $lookup: { from: "partnership", let: { userId: "$_id" }, as: "prob", pipeline: [ { $set: { users: [ "$fromUser", "$toUser" ], u: "$$userId" } }, { $match: { $expr: { $and: [ { $in: [ "$$userId", "$users" ] }, { $in: [ "abc", "$users" ] } ] } } } ] } }, { $match: { "prob.0": { $exists: false } } }, { $sample: { size: 1 } }, { $unset: "prob" } ])
修正方案
问题根源在于$lookup子管道的匹配逻辑:原代码会排除所有和abc有过双向请求的用户,但我们只需要排除abc主动发起请求的用户。修改后仅精准匹配abc作为发起方的请求记录,具体代码如下:
db.users.aggregate([ { $match: { group: 1, _id: { $ne: "abc" } } }, { $lookup: { from: "partnership", let: { userId: "$_id" }, as: "prob", pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$fromUser", "abc"] }, { $eq: ["$toUser", "$$userId"] } ] } } } ] } }, { $match: { "prob.0": { $exists: false } } }, { $sample: { size: 1 } }, { $unset: "prob" } ])
修正说明
- 移除了子管道中冗余的
$set步骤,直接通过请求方向精准筛选 - 子管道仅查询abc作为发起方、当前用户作为接收方的合作请求
- 最终结果会排除123(abc主动发过请求),保留rrr(仅rrr向abc发起请求,abc未反向发送)
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

