将“虚拟”变量添加到mongoose模式?

时间:2013-08-14 18:21:22

标签: node.js mongoose

我有以下文档架构:

var pageSchema = new Schema({
      name: String
    , desc: String
    , url: String
})

现在,在我的应用程序中,我想在对象中有页面的html源代码,但我不想将它存储在数据库中。

我是否应该创建一个“本地”增强对象,该对象具有对db文档的引用?

function Page (docModel, html) {
    this._docModel = docModel
    this._html = html
}

有没有办法通过添加“虚拟”字段直接使用文档模型?

4 个答案:

答案 0 :(得分:35)

这在猫鼬中是完全可能的 查看此示例,取自他们的文档:

var personSchema = new Schema({
  name: {
    first: String,
    last: String
  }
});

personSchema.virtual('name.full').get(function () {
  return this.name.first + ' ' + this.name.last;
});
console.log('%s is insane', bad.name.full); // Walter White is insane

在上面的示例中,该属性没有setter。要为此虚拟机设置一个setter,请执行以下操作:

personSchema.virtual('name.full').get(function () {
  return this.name.full;
}).set(function(name) {
  var split = name.split(' ');
  this.name.first = split[0];
  this.name.last = split[1];
});

Documentation

答案 1 :(得分:12)

我实际上没有测试过这个,但这个想法似乎值得:

//model
var pageSchema = new Schema({
      name: String
    , desc: String
    , url: String
})

pageSchema.virtual('html')
  .get(function(){
    var url = this.url

    function get(url) {
      return new (require('httpclient').HttpClient)({
        method: 'GET',
          url: url
        }).finish().body.read().decodeToString();
    }

    return get(url);
  });


  //controller
  var page = new Page({
    name: "Google"
    , desc: "Search engine"
    , url: "http://google.com"
  });

  var html = page.html;

基本上设置一个名为html的虚拟属性,该属性向正文请求url属性并将其返回。

如果您使用快递和res.send(page),请务必为toJSON输出虚拟属性。

pageSchema.set('toJSON', {
    virtuals: true
});

答案 2 :(得分:12)

__开头的文档属性不会持久保存到db,因此您可以创建虚拟属性并使getter和setter使用this.__html

pageSchema.virtual('html').get(function () {
  return this.__html;
}).set(function (html) {
  this.__html = html;
});

但这有点需要注意:这个功能没有记录,因此没有以__开头的内部属性列表,因此将来有可能(尽管不太可能)内部实现可以开始使用名为__html

的var

https://github.com/Automattic/mongoose/issues/2642

答案 3 :(得分:0)

2020年

您可以通过在模型中的对象下面添加对象来设置虚拟对象。

toJSON: { virtuals: true },
toObject: { virtuals: true }

上面的示例和下面的示例是等效的,但是上面的示例简短而简单。

itemSchema.set('toJSON', {
    virtuals: true
});

这里是例子

模型

const itemsSchema = new mongoose.Schema({
    image: {
        type: String,
        trim: true,
        required: [true, 'Please provide item image']
    },
    color: {
        type: String,
        trim: true
    },
    size: {
        type: String,
        trim: true
    },
    price: {
        type: Number,
        required: [true, 'Please provide item price']
    },
    shipping: {
        type: Number
    },
    discount: {
        type: Number
    },
    details: {
        type: String,
        trim: true
    }
}, {
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
});

设置VirtualSchema

itemsSchema.virtual('totalPrice').get(function() {
    const sub_total = this.price + this.shipping;
    return (sub_total - ( ( sub_total / 100 ) * this.discount )).toFixed(2)
});