2011-11-23 17 views
7

Tengo problemas para resolver cómo insertar múltiples profundidades de esquema anidado en MongoDB, a través de Mongoose y node.js.Nodo, Mangosta, problemas al guardar múltiples profundidades del esquema anidado

El siguiente ejemplo es un poco artificial pero debería explicar mi problema. En cuanto a por qué cada esquema se define como un modelo completo pero no se utiliza en el ejemplo, es solo porque en mi problema del mundo real, son modelos reales utilizables y quería que este ejemplo fuera realista en caso de que fuera relevante.

Aquí están las definiciones de esquema de ejemplo en orden inverso, es decir. más pequeño muñecas rusas primera:

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

Con suerte se puede deducir de esto que existe un modelo principal, stationerybox, que tiene una etiqueta y contiene dos compartimentos para DrawingTools y MeasuringTools cuales están anidados esquema. A su vez, tienen sus propias etiquetas y contienen esquemas anidados para Bolígrafos y Reglas. El problema que tengo es insertar el segundo nivel de anidación, es decir. plumas/reglas. Por lo tanto, en función de los documentos de mangosta, crear el modelo de nivel superior y empujar los primeros objetos anidados funciona bien, a continuación, se produce un problema. Por ejemplo:

// 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' }); 

Y si vuelvo un paso y tratar de insertar las plumas al mismo tiempo que las herramientas de dibujo:

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

Sé que esto no es un ejemplo de super-realistas , pero es un ejemplo simplificado de un sistema del mundo real que estoy construyendo y esta fue la forma más fácil de ilustrarlo.

El ahorro real ocurre después de esto, por supuesto, y lo dejé fuera, pero ¿necesito agregar estos próximos niveles en la devolución de llamada guardada quizás?

Si alguien me puede decir dónde me está yendo mal con esto o si me apunta en la dirección correcta, le compraré un buen pastel (solo me temo que es una torta imaginaria, a menos que viva cerca de mí).

Respuesta

9

Usted está extremadamente cerca, el problema está realmente en sus definiciones Schema. Todo se reduce a la diferencia entre un objeto Schema y un objeto Model. Cuando se especifica mongoose Schema con documentos incrustados, solo puede apuntar a otroSchema.

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

Sin embargo, usted tiene este correcto para el primer nivel de la inclusión de documentos definidos en StationeryBoxSchema.

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

Esta diferencia explicará todo su comportamiento inesperado más adelante.

+1

Gracias Daniel. Por supuesto, tienes toda la razón. Han pasado unos días desde que publiqué el problema original y he aprendido mucho en ese momento, así que no puedo recordar si tratar de insertar el modelo y no el esquema fue solo un error en mi código de ejemplo (en el que caso tuve algo mal en otro lugar) o si cometí el mismo error en mi código del "mundo real" (que ha cambiado mucho desde entonces, así que no puedo verificar;)). Pero como dices, eso explicaría el comportamiento posterior, ¡así que probablemente tengas razón! – tdous

+0

Es un placer - Entiendo que algunos días es mucho tiempo cuando trabajamos en algo como esto. Probablemente la parte más empinada de la curva de aprendizaje de nodo es descubrir cómo depurar problemas que fallan silenciosamente. –

Cuestiones relacionadas