Добавление "виртуальных" переменных в схему мангуста?

У меня есть следующая схема документа:

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

Теперь, в моем приложении, я хотел бы также иметь html-источник страницы внутри объекта, но я не хочу хранить его в db.

Должен ли я создать "локальный" расширенный объект, который имеет ссылку на документ db?

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

Можно ли использовать модель документа напрямую, добавив "виртуальное" поле?

Ответы

Ответ 1

Это вполне возможно в мангусте.
Проверьте этот пример, взятый из их документации:

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

Документация

Ответ 2

Свойства документа, начинающиеся с __, не сохраняются в db, поэтому вы можете создать виртуальное свойство и использовать getter и setter this.__html

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

но это немного взломать с оговоркой: эта функциональность не документирована, поэтому нет списка внутренних свойств, начинающихся с __, поэтому есть вероятность, хотя и маловероятная, что в будущем внутренняя реализация может начать использовать var под названием __html

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

Ответ 3

Я действительно не проверял это, но идея кажется достойной:

//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 и возвращает его.

Обязательно включите вывод виртуальных атрибутов для jSON, если вы используете express и res.send(page).

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