Узел, Mongoose, проблемы с сохранением нескольких глубин вложенной схемы - PullRequest
8 голосов
/ 23 ноября 2011

У меня возникают проблемы при разработке способа вставки вложенных схем нескольких глубин в MongoDB через Mongoose и node.js.

Пример ниже немного надуман, но, надеюсь, должен объяснить мою проблему.Что касается того, почему каждая схема определяется как полная модель, но не используется в примере, то это просто потому, что в моей реальной проблеме они являются актуальными, пригодными для использования моделями, и я хотел, чтобы этот пример был реалистичным в случае его актуальности.

Итак, вот примерные определения схемы в обратном порядке, т.е.сначала самая маленькая русская кукла:

// Define pen model
var PenSchema = new Schema({
  color: String // black, blue or red
});
var Pen = mongoose.model('Pen', PenSchema);

// Define ruler model
var RulerSchema = new Schema({
  units: String // inches or millimetres
});
var Ruler = mongoose.model('Ruler', RulerSchema);

// --------

// Define drawing tools model
var DrawingToolsSchema = new Schema({
  label: String,
  pens: [Pen]
});
var DrawingTools = mongoose.model('DrawingTools', DrawingToolsSchema);

// Define measuring tools model
var MeasuringToolsSchema = new Schema({
  label: String,
  ruler: [Ruler]
});
var MeasuringTools = mongoose.model('MeasuringTools', MeasuringToolsSchema);

// --------

// Define stationery box model
//  It has a label and two compartments - tools for drawing and measuring
var StationeryBoxSchema = new Schema({
  label: String,
  drawingTools: [DrawingToolsSchema],
  measuringTools: [MeasuringToolsSchema]
});
var StationeryBox = mongoose.model('StationeryBox', StationeryBoxSchema);

Надеемся, что из этого можно сказать, что есть основная модель StationeryBox с меткой и двумя отсеками для DrawingTools и MeasuringTools, которые являются вложенной схемой.Они, в свою очередь, имеют свои собственные метки и содержат вложенные схемы для ручек и линейок.У меня проблема вставлена ​​2-го уровня вложенности, т.е.ручки / линейки.Таким образом, на основе документов Мангуста создание модели верхнего уровня и добавление первых вложенных объектов работает нормально, а затем возникают проблемы.Например:

// To create my stationery box - this works
var stationery = new StationeryBox({ label: 'My Stationery Box' });

// To add the nested compartments - this works
stationery.drawingTools.push({ label: 'My Pens' });
stationery.measuringTools.push({ label: 'My Rulers' });

// But this is wrong as 'stationery.drawingTools.pens' is undefined
stationery.drawingTools.pens.push({ color: 'red' });
stationery.drawingTools.pens.push({ color: 'black' });

И если я вернусь на один шаг назад и попытаюсь вставить ручки одновременно с инструментами для рисования:

// Also wrong - presumably the second level of nesting is the problem
stationery.drawingTools.push({
  label: 'My Pens',
  pens: [ // These object represent second levels of nested schema
    { color: 'red' },
    { color: 'black' }
  ]
});

Я знаю, что это несуперреалистичный пример, но это упрощенный пример реальной системы, которую я строю, и это был самый простой способ проиллюстрировать это.

Фактическая экономия происходит после этого, конечно, и я оставил этоно мне нужно добавить эти следующие уровни в функцию обратного вызова save?

Если кто-нибудь может сказать мне, где я ошибаюсь, или указать мне правильное направление, я куплю вам хорошийторт (боюсь только воображаемый торт, если вы не живете рядом со мной).

1 Ответ

10 голосов
/ 26 ноября 2011

Вы очень близки, проблема на самом деле в ваших Schema определениях.Все сводится к разнице между Schema объектом и Model объектом.При указании mongoose Schema со встроенными документами вы можете указывать только на другие Schema.

var DrawingToolsSchema = new Schema({
  label: String,
  pens: [Pen] // uh-oh, broken! Pen is a Model.
});

Однако вы правильно настроили этот параметр для первого уровня встроенных документов.в StationeryBoxSchema.

var StationeryBoxSchema = new Schema({
  label: String,
  drawingTools: [DrawingToolsSchema], // yes! DrawingToolsSchema is a Schema
  measuringTools: [MeasuringToolsSchema] // this one too.
});

Эта разница объясняет все ваши неожиданные действия в дальнейшем.

...