Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Node.js
Code

Una introducción a Mongoose para MongoDB y Node.js

by
Length:LongLanguages:
This post is part of a series called An Introduction to Mongoose for MongoDB and Node.js.
Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

Mongoose es un marco de JavaScript que se usa comúnmente en una aplicación Node.js con una base de datos MongoDB. En este artículo, voy a presentarle Mongoose y MongoDB, y más importante aún, dónde estas tecnologías se adaptan a su aplicación.

¿Qué es MongoDB?

Comencemos con MongoDB. MongoDB es una base de datos que almacena sus datos como documentos. Lo más común es que estos documentos se parezcan a una estructura similar a JSON:

Un documento luego se coloca dentro de una colección. Como ejemplo, el ejemplo de documento anterior define un objeto user. Este objeto user normalmente sería parte de una colección llamada users.

Uno de los factores clave con MongoDB es su flexibilidad cuando se trata de estructura. Aunque en el primer ejemplo, el objeto user contenía una propiedad firstName y lastName, estas propiedades no son necesarias en todos los documentos user que forman parte de la colección users. Esto es lo que hace que MongoDB sea muy diferente de una base de datos SQL como MySQL o Microsoft SQL Server que requiere un esquema de base de datos fuertemente definido de cada objeto que almacena.

La capacidad de crear objetos dinámicos que se almacenan como documentos en la base de datos es donde Mongoose entra en juego.

¿Qué es la Mongoose?

Mangosta es un Object Document Mapper (ODM). Esto significa que Mongoose le permite definir objetos con un esquema fuertemente tipado que se asigna a un documento MongoDB.

Mongoose proporciona una increíble cantidad de funcionalidades para crear y trabajar con esquemas. Mongoose actualmente contiene ocho SchemaTypes que una propiedad se guarda como cuando se conserva a MongoDB. Son:

  1. String (Cadena)
  2. Number (Número)
  3. Date (Fecha)
  4. Buffer
  5. Boolean (Booleano)
  6. Mixed (Mixto)
  7. ObjectId
  8. Array (Matriz)

Cada tipo de datos le permite especificar:

  • un valor predeterminado
  • una función de validación personalizada
  • indica que se requiere un campo
  • una función get que le permite manipular los datos antes de que se devuelva como un objeto
  • una función de conjunto que le permite manipular los datos antes de guardarlos en la base de datos
  • crear índices para permitir que los datos se obtengan más rápido

Además de estas opciones comunes, ciertos tipos de datos le permiten personalizar aún más cómo se almacenan y recuperan los datos de la base de datos. Por ejemplo, un tipo de datos String también le permite especificar las siguientes opciones adicionales:

  • convertirlo a minúsculas
  • convertirlo a mayúsculas
  • recortar datos antes de guardar
  • una expresión regular que puede limitar los datos que se pueden guardar durante el proceso de validación
  • una enumeración que puede definir una lista de cadenas que son válidas

Las propiedades Número Number y Fecha Date son compatibles con la especificación de un valor mínimo y máximo permitido para ese campo.

La mayoría de los ocho tipos de datos permitidos deberían serle familiares. Sin embargo, hay varias excepciones que pueden surgirle, como Buffer, Mixed, ObjectId y Array.

El tipo de datos Buffer le permite guardar datos binarios. Un ejemplo común de datos binarios sería una imagen o un archivo codificado, como un documento PDF.

El tipo de datos Mixed convierte la propiedad en un campo "todo vale". Este campo se parece a cuántos desarrolladores pueden usar MongoDB porque no hay una estructura definida. Tenga cuidado con el uso de este tipo de datos ya que pierde muchas de las excelentes funciones que ofrece Mongoose, como la validación de datos y la detección de cambios de entidades para saber automáticamente si desea actualizar la propiedad al guardar.

El tipo de datos ObjectId comúnmente especifica un enlace a otro documento en su base de datos. Por ejemplo, si tiene una colección de libros y autores, el documento del libro puede contener una propiedad ObjectId que hace referencia al autor específico del documento.

El tipo de datos Array le permite almacenar matrices similares a JavaScript. Con un tipo de datos Array, puede realizar operaciones de matriz JavaScript comunes en ellos, como push, pop, shift, slice, etc.

Recapitulación rápida

Antes de continuar y generar algún código, solo quería recapitular lo que acabamos de aprender. MongoDB es una base de datos que le permite almacenar documentos con una estructura dinámica. Estos documentos se guardan dentro de una colección.

Mongoose es una biblioteca de JavaScript que le permite definir esquemas con datos fuertemente tipados. Una vez que se define un esquema, Mongoose le permite crear un Modelo basado en un esquema específico. Un modelo de mangosta se asigna a un documento MongoDB a través de la definición del esquema del modelo.

Una vez que haya definido sus esquemas y modelos, Mongoose contiene muchas funciones diferentes que le permiten validar, guardar, eliminar y consultar sus datos utilizando las funciones comunes de MongoDB. Hablaré de esto más con los ejemplos concretos del código a seguir.

Instalando MongoDB

Antes de que podamos comenzar a crear nuestros esquemas y modelos de Mongoose, debe instalarse y configurarse MongoDB. Sugeriría visitar la página de descarga de MongoDB. Hay varias opciones diferentes disponibles para instalar. Me he vinculado al servidor de la comunidad. Esto le permite instalar una versión específica para su sistema operativo. MongoDB también ofrece un Enterprise Server y una instalación de soporte en la nube. Dado que se pueden escribir libros completos sobre la instalación, el ajuste y la supervisión de MongoDB, me quedaré con el Community Server.

Una vez que haya descargado e instalado MongoDB para su sistema operativo de su elección, tendrá que iniciar la base de datos. En lugar de reinventar la rueda, sugeriría visitar la documentación de MongoDB sobre cómo instalar MongoDB Community Edition.

Voy a esperar aquí mientras configura MongoDB. Cuando esté listo, podemos pasar a la configuración de Mongoose para conectarse a su base de datos MongoDB recién instalada.

Configuración de Mongoose

Mongoose es un marco de JavaScript, y voy a usarlo en una aplicación Node.js. Si ya tiene Node.js instalado, puede pasar al siguiente paso. Si no tiene instalado Node.js, le sugiero que comience visitando la página de descarga de Node.js y seleccionando el instalador para su sistema operativo.

Con Node.js configurado y listo, voy a crear una nueva aplicación y luego instalar el paquete Mongoose NPM.

Con un símbolo del sistema que está configurado en donde desea instalar su aplicación, puede ejecutar los siguientes comandos:

Para la inicialización de mi aplicación, dejé todo como sus valores predeterminados. Ahora voy a instalar el paquete de mangosta de la siguiente manera:

Con todos los requisitos previos configurados, conéctese a una base de datos MongoDB. Coloqué el siguiente código dentro de un archivo index.js porque lo elegí como punto de partida para mi aplicación:

La primera línea de código incluye la biblioteca mongoose. A continuación, abro una conexión a una base de datos a la que he llamado mongoose_basics utilizando la función connect.

La función connect acepta otros dos parámetros opcionales. El segundo parámetro es un objeto de opciones donde puede definir cosas como el nombre de usuario y la contraseña, si es necesario. El tercer parámetro, que también puede ser el segundo parámetro si no tiene opciones, es la función de devolución de llamada después de intentar conectarse. La función de devolución de llamada se puede usar de una de estas dos formas:

Para evitar una posible introducción a las promesas de JavaScript, usaré la primera. A continuación se muestra un archivo index.js actualizado:

Si se produce un error al conectarse a la base de datos, se lanza la excepción y se detiene todo el procesamiento posterior. Cuando no ocurre ningún error, he registrado un mensaje de éxito en la consola.

Mongoose ahora está configurado y conectado a una base de datos llamada mongoose_basics. Mi conexión MongoDB no usa nombre de usuario, contraseña o puerto personalizado. Si necesita establecer estas opciones o cualquier otra opción durante la conexión, le sugiero que revise la documentación de Mongoose al conectarse. La documentación proporciona explicaciones detalladas de las muchas opciones disponibles, así como también cómo crear conexiones múltiples, agrupación de conexiones, réplicas, etc.

Con una conexión exitosa, sigamos adelante para definir un esquema de Mongoose.

Definiendo un Esquema de Mongoose

Durante la introducción, mostré un objeto user que contenía dos propiedades: firstName y lastName. En el siguiente ejemplo, he traducido ese documento en un esquema de Mongoose:

Este es un esquema muy básico que solo contiene dos propiedades sin atributos asociados. Ampliemos este ejemplo convirtiendo las propiedades de nombre y apellido en objetos secundarios de una propiedad name. La propiedad name comprenderá tanto el nombre como el apellido. También agregaré una propiedad created que sea de tipo Date.

Como puede ver, Mongoose me permite crear esquemas muy flexibles con muchas combinaciones diferentes posibles de cómo puedo organizar mis datos.

En este próximo ejemplo, voy a crear dos nuevos esquemas que demostrarán cómo crear una relación con otro esquema: author y book. El esquema book contendrá una referencia al esquema author.

Arriba está el esquema author que amplía los conceptos del esquema user que creé en el ejemplo anterior. Para vincular el Autor y el Libro juntos, la primera propiedad del esquema author es una propiedad _id que es un tipo de esquema ObjectId. _id es la sintaxis común para crear una clave primaria en Mongoose y MongoDB. Luego, al igual que el esquema user, he definido una propiedad name que contiene el nombre y apellido del autor.

Ampliando el esquema user, author contiene varios otros tipos de esquema String. También agregué un tipo de esquema de Buffer que podría contener la imagen de perfil del autor. La propiedad final contiene la fecha de creación del autor; sin embargo, puede observar que se crea de forma ligeramente diferente porque ha definido un valor predeterminado de "ahora". Cuando un autor persiste en la base de datos, esta propiedad se establecerá en la fecha / hora actual.

Para completar los ejemplos de esquema, creamos un esquema book que contenga una referencia al autor utilizando el tipo de esquema ObjectId:

El esquema book contiene varias propiedades de tipo String. Como se mencionó anteriormente, contiene una referencia al esquema author. Para demostrar aún más las potentes definiciones de esquema, el esquema book también contiene una Array de ratings. Cada calificación consta de un summary, detail, numberOfStars y una propiedad created.

Mongoose le permite la flexibilidad de crear esquemas con referencias a otros esquemas o, como en el ejemplo anterior con la propiedad ratings, le permite crear una Array de propiedades secundarias que podría estar contenida en un esquema relacionado (como libro a autor) o en línea como en el ejemplo anterior (con libro a una Array de calificaciones).

Crear y guardar modelos de Mongoose

Como los esquemas author y book demuestran la flexibilidad del esquema de Mongoose, voy a continuar usando esos esquemas y derivar un modelo Author y Book de ellos.

Un modelo de mangosta, cuando se guarda, crea un documento en MongoDB con las propiedades definidas por el esquema del que se deriva.

Para demostrar la creación y el guardado de un objeto, en este próximo ejemplo, crearé varios objetos: un Modelo de Author y varios Modelos Book. Una vez creados, estos objetos se conservarán en MongoDB utilizando el método save del Modelo.

En el ejemplo anterior, he tapado descaradamente una referencia a mis dos libros más recientes. El ejemplo comienza creando y guardando un jamieObject que se crea a partir de un Modelo Author. Dentro de la función save del jamieObject, si ocurre un error, la aplicación generará una excepción. Cuando el guardado es exitoso, dentro de la función save, los dos objetos del libro se crean y guardan. . De forma similar al jamieObject, si se produce un error al guardar, se genera un error; de lo contrario, se genera un mensaje de éxito en la consola.

Para crear la referencia al Autor, los objetos del libro hacen referencia a la clave primaria _id del esquema author en la propiedad author del esquema book.

Validación de datos antes de guardar

Es bastante común que los datos que terminen creando un modelo se llenen por un formulario en una página web. Debido a esto, es una buena idea validar estos datos antes de guardar el Modelo en MongoDB.

En el siguiente ejemplo, actualicé el esquema de autor anterior para agregar validación en las siguientes propiedades: firstName, twitter, facebook y linkedin

La propiedad firstName ha sido atribuida con la propiedad required. Ahora cuando llamo a la función save, Mongoose devolverá un error con un mensaje que indica que se requiere la propiedad firstName. Elegí no hacer la propiedad lastName requerida en caso de que Cher o Madonna fueran autores en mi base de datos.

Las propiedades twitter, facebook, y linkedin tienen validadores personalizados muy similares que se les aplican. Cada uno de ellos garantiza que los valores comiencen con el nombre de dominio respectivo de las redes sociales. Estos campos no son necesarios, por lo que el validador solo se aplicará cuando se proporcionen datos para esa propiedad.

Búsqueda y actualización de datos

Una introducción a Mongoose no estaría completa sin un ejemplo de buscar un registro y actualizar una o más propiedades en ese objeto.

Mongoose proporciona varias funciones diferentes para encontrar datos para un modelo específico. Las funciones son find, findOne, y findById.

Las funciones find y findOne aceptan un objeto como entrada para búsquedas complejas, mientras que findById acepta solo un valor con una función de devolución de llamada (un ejemplo seguirá en breve). En este próximo ejemplo, voy a demostrar cómo encontrar todos los libros que contienen la cadena "mvc" en su título.

Dentro de la función find, estoy buscando la cadena "mvc" que no distingue entre mayúsculas y minúsculas en la propiedad title. Esto se logra usando la misma sintaxis para buscar una cadena con JavaScript.

La función de búsqueda también se puede encadenar a otros métodos de consulta, where, and, or, limit, sort, any, etc.

Ampliemos el ejemplo anterior para limitar nuestros resultados a los primeros cinco libros y ordenar en la fecha de creación descendente. Esto devolverá hasta los cinco libros más recientes que contengan "mvc" en el título.

Después de aplicar la función find, el orden de las otras funciones no es importante porque todas las funciones encadenadas se compilan juntas en una sola consulta y no se ejecutan hasta que se llama a la función exec.

Como mencioné anteriormente, findById se ejecuta de forma un poco diferente. Se ejecuta inmediatamente y acepta una función de devolución de llamada, en lugar de permitir una cadena de funciones. En este próximo ejemplo, estoy consultando a un autor específico por su _id.

El _id en tu caso puede ser ligeramente diferente. Copié este _id de un console.log anterior al encontrar una lista de libros con "mvc" en su título.

Una vez que un objeto ha sido devuelto, puede modificar cualquiera de sus propiedades para actualizarlo. Una vez que haya realizado los cambios necesarios, llame al método save, al igual que cuando estaba creando el objeto. En este próximo ejemplo, extenderé el ejemplo de findbyId y actualizaré la propiedad linkedin sobre el autor.

Después de que el autor se recupera con éxito, se establece la propiedad linkedin y se invoca la función save. Mongoose es capaz de detectar que la propiedad linkedin se modificó y enviará una declaración de actualización a MongoDB solo sobre las propiedades que se han modificado. Si se produce un error al guardar, se lanzará una excepción y detendrá la aplicación. Cuando tiene éxito, se registra un mensaje de éxito en la consola.

Mongoose también ofrece dos funciones adicionales que hacen que encontrar un objeto y guardarlo en un solo paso con las funciones apropiadamente nombradas: findByIdAndUpdate y findOneAndUpdate. Actualicemos el ejemplo anterior para usar findByIdAndUpdate.

En el ejemplo anterior, las propiedades para actualizar se suministran como un objeto para el segundo parámetro de la función findByIdAndUpdate. La función de devolución de llamada ahora es el tercer parámetro. Cuando la actualización es exitosa, el objeto author devuelto contiene la información actualizada. Esto se registra en la consola para ver las propiedades del autor actualizado.

Código de muestra final

A lo largo de este artículo, proporcioné pequeños fragmentos de código que identifican una acción muy específica, como crear un esquema, crear un modelo, etc. Vamos a poner todo junto en un ejemplo completo.

En primer lugar, he creado dos archivos adicionales: author.js y book.js. Estos archivos contienen sus respectivas definiciones de esquema y la creación del modelo. La última línea de código hace que el modelo esté disponible para su uso en el archivo index.js.

Comencemos con el archivo author.js:

Luego viene el archivo book.js:

Y finalmente, el archivo index.js actualizado:

En el ejemplo anterior, todas las acciones de Mangosta están contenidas dentro de la función connect. Los archivos author y book se incluyen con la función require después de incluir la biblioteca mongoose.

Con MongoDB en ejecución, ahora puede ejecutar la aplicación completa Node.js con el siguiente comando:

Después de guardar algunos datos en mi base de datos, actualicé el archivo index.js con las funciones de búsqueda de la siguiente manera:

Una vez más, puede ejecutar la aplicación con el comando: node index.js.

Resumen

Después de leer este artículo, debe poder crear Esquemas y Modelos Mongoose extremadamente flexibles, aplicar validación simple o compleja, crear y actualizar documentos, y finalmente buscar los documentos que se crearon.

Espero que ahora te sientas cómodo usando Mongoose. Si desea obtener más información, le sugiero que revise las Guías de Mangoose, que profundizan en temas más avanzados, como población, middleware, promesas, etc.

¡Feliz cacería (pobre referencia de animales)!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.