24

我有以下文档架构:

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

现在,在我的应用程序中,我还希望在对象中包含页面的 html 源代码,但我不想将其存储在数据库中。

我应该创建一个引用 db 文档的“本地”增强对象吗?

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

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

4

4 回答 4

37

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

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

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

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];
});

文档

于 2013-08-15T14:50:07.397 回答
14

以开头的文档属性__不会保存到数据库中,因此您可以创建一个虚拟属性并使用 getter 和 setterthis.__html

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

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

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

于 2015-08-23T11:42:29.360 回答
13

我实际上并没有对此进行测试,但这个想法似乎值得:

//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并返回它。

如果您使用 express 和res.send(page).

pageSchema.set('toJSON', {
    virtuals: true
});
于 2014-05-18T06:21:43.090 回答
1

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 }
});

设置虚拟架构

itemsSchema.virtual('totalPrice').get(function() {
    const sub_total = this.price + this.shipping;
    return (sub_total - ( ( sub_total / 100 ) * this.discount )).toFixed(2)
});
于 2020-06-08T15:21:48.467 回答