tutorial node mongoosejs example español mongodb mongoose

mongodb - mongoosejs - node js mongoose crud



¿Por qué Mongoose tiene ambos esquemas y modelos? (4)

Los dos tipos de objetos parecen estar tan cerca unos de otros que tener ambos parece redundante. ¿De qué sirve tener esquemas y modelos?


A menudo, la forma más fácil de responder a este tipo de preguntas es con un ejemplo. En este caso, alguien ya lo hizo por mí :)

Eche un vistazo aquí:

http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/

EDITAR: La publicación original (como se menciona en los comentarios) parece que ya no existe, así que la estoy reproduciendo a continuación. Si alguna vez regresa, o si se acaba de mudar, házmelo saber.

Proporciona una descripción decente del uso de esquemas dentro de los modelos en mangosta y por qué le gustaría hacerlo, y también le muestra cómo enviar tareas a través del modelo, mientras que el esquema tiene que ver con la estructura, etc.

Publicación original:

Comencemos con un ejemplo simple de incrustación de un esquema dentro de un modelo.

var TaskSchema = new Schema({ name: String, priority: Number }); TaskSchema.virtual(''nameandpriority'') .get( function () { return this.name + ''('' + this.priority + '')''; }); TaskSchema.method(''isHighPriority'', function() { if(this.priority === 1) { return true; } else { return false; } }); var ListSchema = new Schema({ name: String, tasks: [TaskSchema] }); mongoose.model(''List'', ListSchema); var List = mongoose.model(''List''); var sampleList = new List({name:''Sample List''});

TaskSchema un nuevo objeto TaskSchema con información básica que una tarea podría tener. Un atributo virtual Mongoose está configurado para combinar convenientemente el nombre y la prioridad de la Tarea. Solo especifiqué un getter aquí, pero los setters virtuales también son compatibles.

También isHighPriority un método de tarea simple llamado isHighPriority para demostrar cómo funcionan los métodos con esta configuración.

En la definición de ListSchema , verá cómo la tecla de tareas está configurada para contener una matriz de objetos TaskSchema . La clave de tarea se convertirá en una instancia de DocumentArray que proporciona métodos especiales para tratar con documentos integrados de Mongo.

Por ahora, solo pasé el objeto ListSchema a mongoose.model y dejé TaskSchema. Técnicamente, no es necesario convertir el TaskSchema en un modelo formal ya que no lo TaskSchema en su propia colección. Más adelante, le mostraré cómo no perjudicará nada si lo hace y puede ayudar a organizar todos sus modelos de la misma manera, especialmente cuando comienzan a abarcar múltiples archivos.

Con la configuración del modelo de List , agreguemos un par de tareas y guárdelas en Mongo.

var List = mongoose.model(''List''); var sampleList = new List({name:''Sample List''}); sampleList.tasks.push( {name:''task one'', priority:1}, {name:''task two'', priority:5} ); sampleList.save(function(err) { if (err) { console.log(''error adding new list''); console.log(err); } else { console.log(''new list successfully saved''); } });

El atributo de tareas en la instancia de nuestro modelo de List ( simpleList ) funciona como una matriz de JavaScript normal y podemos agregarle nuevas tareas usando push. Lo importante es notar que las tareas se agregan como objetos regulares de JavaScript. Es una distinción sutil que puede no ser inmediatamente intuitiva.

Puede verificar desde el shell de Mongo que la nueva lista y las tareas se guardaron en mongo.

db.lists.find() { "tasks" : [ { "_id" : ObjectId("4dd1cbeed77909f507000002"), "priority" : 1, "name" : "task one" }, { "_id" : ObjectId("4dd1cbeed77909f507000003"), "priority" : 5, "name" : "task two" } ], "_id" : ObjectId("4dd1cbeed77909f507000001"), "name" : "Sample List" }

Ahora podemos usar el ObjectId para desplegar la Sample List e iterar a través de sus tareas.

List.findById(''4dd1cbeed77909f507000001'', function(err, list) { console.log(list.name + '' retrieved''); list.tasks.forEach(function(task, index, array) { console.log(task.name); console.log(task.nameandpriority); console.log(task.isHighPriority()); }); });

Si ejecuta ese último bit de código obtendrá un error que dice que el documento incrustado no tiene un método que sea isHighPriority . En la versión actual de Mongoose, no puede acceder directamente a los métodos en esquemas incrustados. Hay un boleto abierto para arreglarlo y después de hacerle la pregunta al Grupo Mongoose de Google, manimal45 publicó un útil trabajo de ayuda para usar por el momento.

List.findById(''4dd1cbeed77909f507000001'', function(err, list) { console.log(list.name + '' retrieved''); list.tasks.forEach(function(task, index, array) { console.log(task.name); console.log(task.nameandpriority); console.log(task._schema.methods.isHighPriority.apply(task)); }); });

Si ejecuta ese código, debería ver la siguiente salida en la línea de comando.

Sample List retrieved task one task one (1) true task two task two (5) false

Con esa TaskSchema en mente, TaskSchema el TaskSchema en un modelo Mongoose.

mongoose.model(''Task'', TaskSchema); var Task = mongoose.model(''Task''); var ListSchema = new Schema({ name: String, tasks: [Task.schema] }); mongoose.model(''List'', ListSchema); var List = mongoose.model(''List'');

La definición de TaskSchema es la misma que antes, así que lo dejé fuera. Una vez que se convirtió en un modelo, aún podemos acceder a su objeto Schema subyacente mediante la notación de puntos.

Creemos una nueva lista e incorporemos dos instancias de modelo de tarea dentro de ella.

var demoList = new List({name:''Demo List''}); var taskThree = new Task({name:''task three'', priority:10}); var taskFour = new Task({name:''task four'', priority:11}); demoList.tasks.push(taskThree.toObject(), taskFour.toObject()); demoList.save(function(err) { if (err) { console.log(''error adding new list''); console.log(err); } else { console.log(''new list successfully saved''); } });

A medida que incorporamos las instancias del modelo de tareas en la Lista, llamamos toObject sobre ellas para convertir sus datos en objetos JavaScript simples que espera List.tasks DocumentArray . Cuando guarde instancias de modelo de esta manera, sus documentos incrustados contendrán ObjectIds .

El ejemplo de código completo está disponible como esencia . Afortunadamente estas soluciones ayudan a suavizar las cosas a medida que Mongoose continúa desarrollándose. Todavía soy bastante nuevo para Mongoose y MongoDB, así que no dude en compartir mejores soluciones y sugerencias en los comentarios. ¡Feliz modelado de datos!


En palabras simples,

Un modelo es un modelo de objetos de datos, como el que se encontraría en un patrón de diseño de MVC. Define la estructura de qué tipo de datos debe almacenarse en una base de datos y qué tipo de relación tienen los datos.

Un esquema es como un database schema , la definición de lo que se almacenará en una base de datos.


No creo que la respuesta aceptada realmente responda la pregunta que se planteó. La respuesta no explica por qué Mongoose ha decidido exigir a un desarrollador que proporcione tanto un esquema como una variable de modelo. Un ejemplo de un marco donde han eliminado la necesidad de que el desarrollador defina el esquema de datos es django: un desarrollador escribe sus modelos en el archivo models.py y lo deja en el marco para administrar el esquema. La primera razón que me viene a la mente de por qué lo hacen, dada mi experiencia con django, es la facilidad de uso. Quizás lo más importante es el principio DRY (no te repitas), no tienes que acordarte de actualizar el esquema cuando cambies el modelo. ¡Django lo hará por ti! Rails también administra el esquema de los datos para usted: un desarrollador no edita el esquema directamente, sino que lo modifica definiendo las migraciones que manipulan el esquema.

Una razón por la que pude entender que Mongoose separaría el esquema y el modelo son los casos en los que desearía construir un modelo a partir de dos esquemas. Tal escenario puede presentar más complejidad de la que vale la pena administrar: si tiene dos esquemas que son administrados por un modelo, ¿por qué no son un esquema?

Quizás la pregunta original es más una reliquia del sistema de base de datos relacional tradicional. En World NoSQL / Mongo world, quizás el esquema sea un poco más flexible que MySQL / PostgreSQL, y por lo tanto, cambiar el esquema es una práctica más común.


Schema es un objeto que define la estructura de cualquier documento que se almacenará en su colección MongoDB; le permite definir tipos y validadores para todos sus elementos de datos.

El modelo es un objeto que le brinda acceso fácil a una colección con nombre, lo que le permite consultar la colección y usar el esquema para validar cualquier documento que guarde en esa colección. Se crea al combinar un esquema, una conexión y un nombre de colección.

Originalmente redactado por Valeri Karpov, MongoDB Blog