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,所以也不能用于查询