MongoDB 3.4版本下如何通过$lookup关联数组字段查询用户所属组
MongoDB 3.4 适配的用户-组关联查询实现方案
3.4版本能力边界说明
MongoDB 3.4版本自带的$lookup能力完全可以满足当前关联需求,无需依赖3.6+版本才支持的pipeline自定义匹配语法:
- 3.4版本的
$lookup仅支持固定格式的等值关联:指定当前集合的本地标量字段,与关联集合的任意字段(包含数组类型字段)做等值匹配 - 当关联集合的匹配字段为数组类型时,MongoDB会自动匹配:只要数组中任意元素等于当前文档的本地字段值,就会将该关联文档纳入结果集,匹配逻辑和
$in查询完全一致 - 当前的关联场景刚好适配这个原生能力:从用户集合出发,用用户本身的
_id(标量值),匹配组集合中userIds数组包含该用户ID的所有组文档
可直接运行的聚合管道
所有用到的聚合阶段均为3.4版本原生支持,无版本依赖:
// 在USERS用户集合上执行聚合操作 db.USERS.aggregate([ // 关联匹配所有包含当前用户ID的组文档 { $lookup: { from: "GROUPS", // 关联用户组集合 localField: "_id", // 对应当前用户的主键字段 foreignField: "userIds", // 组集合的用户ID数组字段,自动做数组元素匹配 as: "matchedGroups" // 匹配到的组列表,固定返回数组结构 } }, // 裁剪字段,对齐期望的输出结构 { $project: { email: 1, // 保留用户邮箱字段 // 裁剪组列表字段,仅保留组_id和名称 groups: { $map: { input: "$matchedGroups", as: "groupItem", in: { _id: "$$groupItem._id", name: "$$groupItem.name" } } } } } ])
输出结构验证
执行上述管道后,返回结果和你期望的格式完全一致,无任何结构偏差:
- 所有用户都会被返回,哪怕是没有加入任何组的用户,
groups字段会自动返回空数组 - 每个用户的
groups数组仅包含组的_id和name字段,无多余冗余字段
优化提示
- 提前在GROUPS集合的
userIds字段创建多键索引,可大幅降低关联查询的扫描开销 - 如果需要对匹配的组增加过滤规则(比如仅关联状态为启用的组),可在管道中追加
$filter阶段对matchedGroups数组做条件筛选,不需要依赖高版本的pipeline式$lookup语法
内容的提问来源于stack exchange,提问作者You Know Who
相关产品推荐
相关产品推荐

