virtuals 是什么?
virtuals 是 mongoose 的计算属性,不真实存储在 mongodb,但是可以在 mongodb 写入和返回的时间节点上处理数据,类似于 vue 的 computed
virtuals 实战
比如我的博客文章,在显示文章卡片的时候需要针对文章内容进行文本截取,输出一个 shortContent
字段(如下图)。这时候 virtuals 就可以派上用场了。
virtuals 有两个方法,一个是 get
,一个是 set
,比如现在的 article 的结构如下
const ArticleSchema = new mongoose.Schema({ title: { type: String, required: true }, content: { type: String, required: true }, ...});
接下来给 ArticleSchema 添加计算属性,定义 get 方法,这样 mongoose 在返回的数据格式化的时候就会自动新增一个 shortContent 属性,返回经过处理后的值。
ArticleSchema.virtual('shortContent').get(function () { return util.replaceHTMLTag(this.content).substring(0, 100);});
如果使用
toJson()
或者toObject()
,mongoose 不会输出 virtuals 字段,需要配置参数toJson({ virtuals: true })
或者toObject({ virtuals: true })
才能生效
set
方法适用于一个字段可以拆分成多个字段存储。比如前端传一个 fullName
字段。
const personSchema = new Schema({ first: String, last: String,});personSchema .virtual('fullName') .get(function () { return this.first + ' ' + this.last; }) .set(function (v) { this.first = v.substr(0, v.indexOf(' ')); this.last = v.substr(v.indexOf(' ') + 1); });const Person = mongoose.model('Person', personSchema);const newPerson = new Person({ fullName: 'kelen huang',});// 这时候first,last也会自动设置newPerson.first = 'kelen';newPerson.last = 'huang';
注:
fullName
不会存储在 mongodb,所以也不能用于查询