获取有权限访问指定Circle的用户的MongoDB查询方案
获取有权限访问Circle的用户查询方案
我有以下两个Mongoose Schema:
User Schema
const mongoose = require("mongoose"); const validator = require("validator"); const userSchema = new mongoose.Schema( { name: { type: String, required: [true, "Name is required"], trim: true, }, email: { type: String, required: [true, "Email is required"], validate: validator.isEmail, trim: true, }, }, { timestamps: true, } ); module.exports = userSchema;
Circle Schema
const mongoose = require("mongoose"); const circlesSchema = new mongoose.Schema( { circleName: { type: String, required: [true, "Circle name is required"], trim: true, unique: [true, "Circle name is already exists"], }, blockedUsers: [{ type: mongoose.Schema.Types.ObjectId, ref: "Users" }], }, { timestamps: true, } ); module.exports = circlesSchema;
需求:Circle的blockedUsers数组存储被禁止访问的用户ObjectID,需要获取所有有权限访问指定Circle的用户(包含name字段)。
解决方案
方法1:MongoDB原生查询
先获取目标Circle的blockedUsers列表,再查询不在该列表中的用户:
- 获取目标Circle的封禁用户ID数组:
// 替换为你要查询的Circle名称 db.circles.findOne({ circleName: "TestCircle" }, { blockedUsers: 1, _id: 0 })
- 查询有权限的用户:
// 将第一步得到的blockedUsers数组替换到此处 db.users.find( { _id: { $nin: [ObjectId("用户ID1"), ObjectId("用户ID2")] } }, { name: 1, email: 1 } // 指定返回字段,确保包含name )
方法2:Mongoose链式查询(适配你的代码场景)
通过Mongoose先定位目标Circle,再筛选出未被封禁的用户:
const Circle = mongoose.model("Circle", circlesSchema); const User = mongoose.model("User", userSchema); async function getAccessibleUsers(circleName) { // 获取目标Circle的封禁用户列表 const targetCircle = await Circle.findOne({ circleName }, "blockedUsers"); if (!targetCircle) throw new Error("指定Circle不存在"); // 查询不在封禁列表中的用户,返回指定字段 const accessibleUsers = await User.find( { _id: { $nin: targetCircle.blockedUsers } }, "name email" ); return accessibleUsers; } // 调用示例 getAccessibleUsers("TestCircle") .then(users => console.log(users)) .catch(err => console.error(err));
关键说明
$nin操作符用于匹配不在指定数组内的文档,正好满足"未被封禁即有权限"的规则- 查询时通过第二个参数指定返回字段,可减少数据传输量,提升查询性能
- 若Circle的
blockedUsers为空数组,$nin会匹配所有用户,符合预期逻辑
内容的提问来源于stack exchange,提问作者imkumawat
相关产品推荐
相关产品推荐

