使用Mongoose virtual populate配置match时报_id未定义TypeError错误
问题原因
你出现该报错的核心是定义虚拟关联时match配置的上下文指向错误:
虚拟关联的配置对象在Schema定义阶段就会同步执行,此时你直接在options.match中写{ subscriberId: this._id },这里的this指向的是Schema定义所在的外层上下文,并不是后续查询得到的User文档实例,不存在_id属性,因此抛出类型错误。
解决方案
Mongoose 5.12及以上版本支持match配置为函数,函数执行时this会自动绑定当前父文档实例,调整虚拟关联写法即可:
const userSchema = mongoose.Schema( { channelName: { type: String, required: [true, 'Please add a channel name'], unique: true, uniqueCaseInsensitive: true } }, { toJSON: { virtuals: true }, toObject: { virtuals: true }, timestamps: true } ); userSchema.virtual('subscribers', { ref: 'Subscription', localField: '_id', foreignField: 'channelId', justOne: false, count: true, // match直接作为顶层配置项,用普通函数返回过滤条件 match: function() { return { subscriberId: this._id } } });
注意事项
- 此处不能使用箭头函数定义match,箭头函数会继承外层上下文的
this,无法绑定到文档实例 - 不需要将match放到
options配置项中,直接写在虚拟关联的顶层配置里即可 - 如果你的Mongoose版本低于5.12,需要先升级版本才能支持该写法
内容的提问来源于stack exchange,提问作者Mahmoud Yasser
相关产品推荐
相关产品推荐

