能否在Mongoose查询结果中获取虚拟属性?求Person模型fullName优雅用法
如何在Mongoose查询结果中获取虚拟属性
当然可以在Mongoose的查询结果里拿到虚拟属性!默认情况下Mongoose不会把虚拟属性自动包含到查询返回的JSON或对象中,只需要做简单配置就能解决这个问题,下面给你两种优雅的实现方式:
方法一:全局Schema配置(推荐)
在定义PersonSchema的时候,添加toJSON和toObject选项,开启虚拟属性的输出:
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const PersonSchema = new Schema( { firstName: {type: String, required: true, max: 100}, lastName: {type: String, required: true, max: 100} }, // 新增这个配置块,让虚拟属性在JSON和对象转换时可见 { toJSON: { virtuals: true }, toObject: { virtuals: true } } ); PersonSchema .virtual('fullName') .get(function () { return this.firstName + ' ' + this.lastName; }); module.exports = mongoose.model('Person', PersonSchema);
这样配置后,所有查询返回的Person文档实例都能直接访问fullName,而且当你把文档转换成JSON(比如接口返回)或者普通JavaScript对象时,虚拟属性也会被包含进去:
// 查询单个用户示例 Person.findById('your-person-id') .then(person => { console.log(person.fullName); // 直接输出 "John Doe" 这类拼接后的全名 console.log(person.toJSON()); // 输出的JSON对象里包含fullName字段 }) .catch(err => console.error(err));
方法二:单个查询临时配置(适合特殊场景)
如果你不想全局开启虚拟属性输出,或者使用了lean()查询(返回普通JS对象而非Mongoose文档),可以在查询时显式指定包含虚拟属性:
// 使用lean()查询并包含虚拟属性 Person.find().lean({ virtuals: true }) .then(people => { people.forEach(person => { console.log(person.fullName); // 同样能拿到拼接后的全名 }); }) .catch(err => console.error(err));
注意:lean()会跳过Mongoose的文档实例包装,性能更高,但默认不包含虚拟属性,所以必须加上{ virtuals: true }参数才能获取到fullName。
小提示
定义虚拟属性的get函数里,尽量用普通函数(不要用箭头函数),这样this才能指向当前的文档实例,正确获取firstName和lastName的值。
内容的提问来源于stack exchange,提问作者user9675390
相关产品推荐
相关产品推荐

