如何在Mongoose的Schema自身方法中查询所属的MongoDB集合?
错误根因
mongoose.Collection是Mongoose内置的集合基类构造函数,并非你的业务中对应User集合的操作实例,所以直接调用find方法必然报错。你之前尝试用this直接调用查询方法报错,是因为实例方法中的this指向单个User文档实例,并非集合模型,只有模型才能调用find/findOne这类集合查询方法。
解决方案
在Schema实例方法中可以通过以下两种方式获取User模型完成查询:
- 方式1:通过
this.constructor获取当前文档实例关联的模型(最推荐,不需要依赖模型的注册名称)
实例方法中的this指向当前User文档实例,它的constructor属性就是你编译好的User模型,可以直接调用查询方法。
注意你代码中存在字段大小写错误:Schema定义的字段是publicUsername(最后一个单词首字母小写),你查询语句里写的是publicUserName(最后一个单词首字母大写),字段名不匹配会导致查询结果不符合预期,需要修正。
修正后的完整代码如下:
UserSchema.methods.generateRandomUserName = async function(){ let username; let isExist = true; // 循环生成直到用户名不重复 while(isExist){ // 此处替换为你自己的随机用户名生成逻辑 username = `user_${Math.random().toString(36).slice(2, 10)}`; // 通过this.constructor拿到User模型查询 const existUser = await this.constructor.findOne({ publicUsername: username }); isExist = !!existUser; } this.publicUsername = username; return username; }
- 方式2:通过
mongoose.model直接获取已注册的User模型
如果你已经提前通过mongoose.model('User', UserSchema)将Schema编译为名为User的模型,也可以直接调用:
// 注意该写法需要确保调用generateRandomUserName时,User模型已经完成注册 const User = mongoose.model('User'); const existUser = await User.findOne({ publicUsername: username });
注意事项
- 优先选择
this.constructor的方式,不需要硬编码模型名称,后续修改模型名也不需要调整实例方法的代码 - 查询单个用户是否存在优先用
findOne而不是find,性能更好,返回结果判断也更简单 - 随机用户名的生成逻辑可以根据业务需求调整复杂度,降低碰撞概率减少循环次数
内容的提问来源于stack exchange,提问作者anileates
相关产品推荐
相关产品推荐

