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);
}
Как я могу заверить, что:
Каждый раз, когда новый объект "гидратируется" из db (mongoose init), у меня будет экземпляр Polygon, а не простой объект. Я понимаю, что будет использовать
cast
функция.assert(model.polygon instanceof Polygon)
Каждый раз, когда я сохраняю свою модель, атрибут Polygon должен быть закодирован и сохранен как представление простого объекта (
Polygon.prototype.toObject()
) что в данном случае являетсяArray
объект в mongodb.- Если я использую
model.toObject()
это будет рекурсивно вызыватьmodel.polygon.toObject()
иметь полное простое объектное представление документа.
1 ответ
Я нашел решение благодаря @vkarpov15 на github.com:
SchemaType.prototype.cast()
необходим для правильной гидратации модели документа из необработанного представления mongodb и выдачи ошибки в случае неверных данных.Чтобы настроить постоянство mongodb, мне пришлось реализовать
toBSON()
функция в моем прототипе объекта пользовательского типа (т.е.Polygon
).model.toObject()
/model.toJSON()
в настоящее время не вызывает рекурсивноtoObject()
/toJSON()
на всех детей, но, похоже, это будет исправлено. Но я мог бы перегружать его как временный обходной путь, назначаяschema.methods.toObject()
метод экземпляра.