MongoDB 3.6聚合查询问题:单投影实现两次查询需求
解决MongoDB 3.6中整合角色用户数据的聚合查询方案
嘿,我完全懂你现在的困扰——想把针对Roles集合的两次查询逻辑整合到单个聚合投影里对吧?结合你的集合结构(每个文档对应一个角色,附带Users数组),我给你一个适配MongoDB 3.6语法的具体聚合管道方案。
假设你原本的两次查询是分别提取admin角色的用户列表,以及others、users角色的用户列表,现在要把这两组数据整合到一个结果文档里,用下面的聚合脚本就能实现:
db.Roles.aggregate([ // 第一步:筛选目标角色文档,减少后续处理的数据量 { $match: { RoleName: { $in: ['admin', 'others', 'users'] } } }, // 第二步:分组聚合,分别收集不同角色的用户数组 { $group: { _id: null, // 不按角色分组,把所有数据聚合到一个文档中 adminUsers: { $push: { $cond: { if: { $eq: ['$RoleName', 'admin'] }, then: '$Users', else: [] // 非admin角色传入空数组,不影响后续合并 } } }, otherUsers: { $push: { $cond: { if: { $in: ['$RoleName', ['others', 'users']] }, then: '$Users', else: [] } } } } }, // 第三步:把嵌套数组合并为一维数组,让结果更整洁 { $project: { _id: 0, // 去除默认的_id字段 adminUsers: { $reduce: { input: '$adminUsers', initialValue: [], in: { $concatArrays: ['$$value', '$$this'] } } }, otherUsers: { $reduce: { input: '$otherUsers', initialValue: [], in: { $concatArrays: ['$$value', '$$this'] } } } } } ])
步骤细节说明:
- $match阶段:先过滤出目标角色的文档,避免处理无关数据,直接提升查询效率。
- $group阶段:通过
$cond条件判断,分别收集admin角色和其他角色的Users数组,这里用$push会生成嵌套数组,所以需要后续处理来扁平化。 - $project阶段:用
$reduce结合$concatArrays把嵌套的数组合并成一维数组,最终得到干净的用户列表。
如果你的需求是把所有角色的用户按角色分类展示(每个角色对应一个独立的用户数组文档),可以调整成下面的版本:
db.Roles.aggregate([ { $match: { RoleName: { $in: ['admin', 'others', 'users'] } } }, { $group: { _id: '$RoleName', users: { $first: '$Users' } // 每个角色仅一个文档,直接取Users数组 } }, { $project: { _id: 0, role: '$_id', users: 1 } } ])
这个版本会返回三个独立文档,每个文档包含角色名和对应的用户数组,同样把多步逻辑整合到了单个聚合管道里。
内容的提问来源于stack exchange,提问作者Im Flash
相关产品推荐
相关产品推荐

