为何对象中明确存在对应key,访问时却返回undefined(Mongoose场景)
问题原因及解决方法
- 原因1:Mongoose查询返回对象类型问题
你调用subscriptionModel.find()时没有加lean()方法,返回的boughtUsers数组里的元素是Mongoose Document实例,不是普通JS对象。控制台打印Document实例时会自动序列化输出所有存储字段,但直接用点语法访问对应字段时,会因为Document实例的访问逻辑限制返回undefined。 - 原因2:ObjectId比较逻辑错误
就算正确获取到了boughtUser.user的值,它和curr?.user?._id都是ObjectId引用类型,直接用===比较会因为内存地址不同,就算值完全一致也返回false,必须用Mongoose内置的比较方法判断相等。
修复后的代码
const docs = await this.walletModel.find({ status: 'Venus' }).select('user meteorite').populate('user', 'name extra.profilePic extra.thumbnail').lean() const userIds = docs.map(user => Types.ObjectId(user?.user?._id)) // 新增lean() 直接返回普通JS对象,避免Document实例访问问题 const boughtUsers = await this.subscriptionModel.find({ user: { $in: userIds } }).select('-_id user').lean() const reduced = docs.reduce((acc, curr) => { if (boughtUsers.some(boughtUser => { // 使用.equals方法比较两个ObjectId的值是否相等 return boughtUser?.user?.equals(curr?.user?._id) })) return [...acc, {...curr}] return [...acc, {...curr, gift: true}] }, []) return reduced
如果你不想在查询时加lean(),也可以通过boughtUser.get('user')的方式主动获取Document实例上的字段值,效果一致。
内容的提问来源于stack exchange,提问作者AuroPick
相关产品推荐
相关产品推荐

