Mongoose расширенный пользовательский тип объекта схемы

Я не смог найти ни одного примера расширенного пользовательского типа схемы, включающего пользовательские объекты (или объекты-значения) в Mongoose >=4.4.

Представьте, что я хочу использовать пользовательский тип, такой как:

function Polygon(c) {
  this.bounds = [ /* some data */ ];
  this.npoints = /* ... */
  /* ... initialize polygon ... */
};

Polygon.prototype.area = function surfaceArea() { /**/ };

Polygon.prototype.toObject = function toObject() { return this.bounds; };

Далее я реализую собственный SchemaType, например:

function PolygonType(key, options) {
  mongoose.SchemaType.call(this, key, options, 'PolygonType');
}

PolygonType.prototype = Object.create(mongoose.SchemaType.prototype);

PolygonType.prototype.cast = function(val) {
  if (!val) return null;
  if (val instanceof Polygon) return val;
  return new Polygon(val)
}

PolygonType.prototype.default = function(val) {
  return new Polygon(val);
}

Как я могу заверить, что:

  1. Каждый раз, когда новый объект "гидратируется" из db (mongoose init), у меня будет экземпляр Polygon, а не простой объект. Я понимаю, что будет использовать cast функция. assert(model.polygon instanceof Polygon)

  2. Каждый раз, когда я сохраняю свою модель, атрибут Polygon должен быть закодирован и сохранен как представление простого объекта (Polygon.prototype.toObject()) что в данном случае является Array объект в mongodb.

  3. Если я использую model.toObject() это будет рекурсивно вызывать model.polygon.toObject() иметь полное простое объектное представление документа.

1 ответ

Решение

Я нашел решение благодаря @vkarpov15 на github.com:

  1. SchemaType.prototype.cast() необходим для правильной гидратации модели документа из необработанного представления mongodb и выдачи ошибки в случае неверных данных.

  2. Чтобы настроить постоянство mongodb, мне пришлось реализовать toBSON() функция в моем прототипе объекта пользовательского типа (т.е. Polygon).

  3. model.toObject() / model.toJSON() в настоящее время не вызывает рекурсивно toObject() / toJSON() на всех детей, но, похоже, это будет исправлено. Но я мог бы перегружать его как временный обходной путь, назначая schema.methods.toObject() метод экземпляра.

Другие вопросы по тегам