node.js 将“虚拟”变量添加到猫鼬模式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18239358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:18:47  来源:igfitidea点击:

Adding 'virtual' variables to a mongoose schema?

node.jsmongoose

提问by fusio

I have the following document schema:

我有以下文档架构:

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

Now, in my application I would like to also have the html source of the page inside the object, but I do not want to store it in the db.

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

Should I create a "local" enhanced object which has a reference to the db document?

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

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

Is there a way to use the document model directly by adding a "virtual" field?

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

回答by gustavohenke

This is perfectly possible in mongoose.
Check this example, taken from their documentation:

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

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

In the above example, the property would not have a setter. To have a setter for this virtual, do this:

在上面的示例中,该属性没有设置器。要为此虚拟设置一个 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

文档

回答by chovy

I have not actually tested this but the idea seems worthy:

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

//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;

Basically set a virtual attribute called htmlwhich requests the body for the urlattribute and returns it.

基本上设置一个名为的虚拟属性html,它请求属性的主体url并返回它。

Be sure to enable outputting of virtual attributes for toJSON if you are using express and res.send(page).

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

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

回答by techjeffharris

Document properties that start with __are not persisted to the db, so you could create a virtual property and have the getter and setter use this.__html

与启动文档属性__不会被持久化到数据库,所以你可以创建一个虚拟的财产,有getter和setter使用this.__html

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

but this is a bit of a hack with a caveat: this functionality is not documented so there is no list of internal properties that start with __so there is a possibility, albeit unlikely, that in the future the internal implementation could start using a var called __html

但这是一个带有警告的黑客:此功能未记录在案,因此没有以开头的内部属性列表,__因此有可能,尽管不太可能,将来内部实现可以开始使用名为的 var__html

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

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