JavaScript+MongoDB如何查询scopes中包含指定accountId的Roles数据
优化方案
核心思路
- 优先在数据库层面过滤出符合条件的Roles,避免全量数据拉取到应用层遍历
- 替换原有N+1查询逻辑,仅用2次数据库查询完成需求,大幅降低IO和时间消耗
具体实现说明
绝大多数数据库(MongoDB、PostgreSQL等)以及常用ORM都支持直接对内嵌数组字段做匹配查询,不需要把数据拉到应用层再循环判断:
- 如果是MongoDB原生查询,过滤符合条件Roles的条件写法为
{ "scopes.account": accountId },可以直接返回所有scopes数组中存在至少一个元素account字段等于目标accountId的Roles记录 - 如果是Loopback等ORM,查询语法也支持嵌套字段匹配,写法参考下方完整代码
完整优化后代码
User.subUsers = async function(accessToken, cb) { try { const accountId = accessToken.accountId; // 1. 数据库层直接过滤出scopes包含指定accountId的角色,仅取id字段减少数据传输 const matchedRoles = await User.app.models.roles.find({ where: { 'scopes.account': accountId }, fields: { id: true } }) const roleIdList = matchedRoles.map(role => role.id) // 2. 批量查询绑定了这些角色的用户,仅返回业务需要的字段优化内存占用 const userData = await User.find({ where: { roleId: { inq: roleIdList } }, fields: { email: true, id: true } }) return cb(null, userData) } catch (err) { return cb(err) } };
额外提速建议
给两个字段添加数据库索引,查询速度可再提升数倍:
- Roles集合的
scopes.account字段 - User集合的
roleId字段
内容的提问来源于stack exchange,提问作者Parikshit Rathore
相关产品推荐
相关产品推荐

