mongoose 4.9.8中按数组内ObjectId查询文档的问题
解决Mongoose 4.9.8中查询数组包含指定ObjectId的问题
我之前也踩过类似的坑,结合你用的Mongoose 4.9.8版本,给你梳理下问题根源和可行的解决方案:
问题拆解
ReferenceError: ObjectId is not defined:这是因为Node.js环境下,Mongoose不会把ObjectId暴露为全局变量(和Mongo Shell的环境不一样),直接调用ObjectId()自然会报错。- 用
mongoose.Schema.ObjectId(123)返回错误结果:mongoose.Schema.ObjectId是用来定义Schema字段类型的构造器(比如写tenants: [{ type: mongoose.Schema.ObjectId }]),不是用来生成具体ObjectId实例的工具。用它构造查询条件会生成无效的查询逻辑,导致Mongoose匹配了完全相反的结果。
正确解决方案
你只需要从mongoose.Types中获取合法的ObjectId构造器来生成查询条件即可:
// 先获取ObjectId构造器 const ObjectId = mongoose.Types.ObjectId; // 执行查询 things.find({ 'tenants': ObjectId('123') }) .then(matchingDocs => { console.log('匹配到的文档:', matchingDocs); }) .catch(err => { console.error('查询出错:', err); });
也可以直接在查询语句里调用,省去单独赋值的步骤:
things.find({ 'tenants': mongoose.Types.ObjectId('123') })
这个方法在Mongoose 4.x版本(包括你用的4.9.8)完全有效,因为mongoose.Types.ObjectId从早期版本就提供了生成ObjectId实例的能力,生成的查询逻辑和原生MongoDB语法完全一致,能精准匹配tenants数组中包含指定ObjectId的文档。
额外验证小技巧
如果担心查询逻辑不对,可以打印出生成的查询语句确认:
const query = things.find({ 'tenants': mongoose.Types.ObjectId('123') }); console.log(query.getQuery()); // 会输出 { tenants: ObjectId("123") },和原生语法完全一致
内容的提问来源于stack exchange,提问作者j-p
相关产品推荐
相关产品推荐

