MongoDB聚合中如何实现嵌套$lookup关联查询?
解决MongoDB嵌套$lookup关联用户与评论的问题
要实现文章关联评论,同时每个评论关联对应用户的需求,有两种可行的聚合方案:
方案一:通用版本(兼容所有MongoDB版本)
通过$unwind拆分评论数组,关联用户后再重新聚合,步骤清晰:
db.posts.aggregate([ // 关联评论集合,获取当前文章的所有评论 { $lookup: { from: 'comments', localField: 'id', foreignField: 'post_id', as: 'comments' } }, // 拆分评论数组为单个文档,保留无评论的文章 { $unwind: { path: '$comments', preserveNullAndEmptyArrays: true } }, // 通过评论的user_id关联用户集合 { $lookup: { from: 'users', localField: 'comments.user_id', foreignField: 'id', as: 'comments.user' } }, // 将用户数组转为单个对象(每个评论仅对应一个用户) { $unwind: { path: '$comments.user', preserveNullAndEmptyArrays: true } }, // 按文章ID重新分组,恢复评论数组结构 { $group: { _id: '$id', title: { $first: '$title' }, content: { $first: '$content' }, comments: { $push: '$comments' } } }, // 可选:把_id重命名为id,和原数据结构一致 { $project: { _id: 0, id: '$_id', title: 1, content: 1, comments: 1 } } ])
方案二:简洁版本(MongoDB 3.6+支持)
利用嵌套$lookup的pipeline特性,直接在关联评论时完成用户关联,无需拆分和重新分组:
db.posts.aggregate([ { $lookup: { from: 'comments', let: { postId: '$id' }, pipeline: [ // 匹配当前文章的评论 { $match: { $expr: { $eq: ['$post_id', '$$postId'] } } }, // 嵌套关联用户集合 { $lookup: { from: 'users', localField: 'user_id', foreignField: 'id', as: 'user' } }, // 将用户数组转为单个对象 { $unwind: { path: '$user', preserveNullAndEmptyArrays: true } } ], as: 'comments' } }, // 保留需要的字段 { $project: { id: 1, title: 1, content: 1, comments: 1 } } ])
预期结果
执行后会得到包含用户信息的评论列表:
{ id: 1, title: 'my title', content: 'bla bla bla', comments: [ { post_id: 1, user_id: '123', content: 'great article!!!', user: { id: '123', name: 'Ferb' } } ] }
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

