mongoose

Docs

¿Qué es mongoose?

Es una librería de NodeJs que funciona como intermediario entre una base de datos MongoDB y un servidor

Permite traducir los datos y las funciones de la base de datos a Objetos Relacionales

¿Si ya existe la librería mongodb (la que utilizamos en el curso de MongoDB) para qué necesitamos mongoose?

mongoose funciona sobre la librería mongodb pero nos permite darle estructura, legibilidad, seguridad y acelerar la velocidad de desarrollo

Flexibilidad

Arma de doble filo

¿Para qué sirve mongoose?

  • Abstraer el uso de una base datos a un lenguaje orientado a objetos
  • Facilitar el desarrollo, mantenimiento y evolución de la arquitectura de datos
  • Automatizar el casteo y validación de datos
  • Evitar vulnerabilidades durante ataques

¿Cómo se utiliza Mongoose?

Mongoose es una librería de JS que se distribuye en los paquetes de NodeJs (npm)

Para instalarlo, aseguarse de tener NodeJs instalado, corriendo este comando en la Terminal de Comandos

 node --version 

Accesar a la carpeta donde se desarrolla el proyecto de Node e instalar

 npm install mongoose --save 

Conexión a la base de datos

Como cualquier paquete de node, hay que importarlo con el comando require


              var mongoose = require('mongoose');
              // Para conectarnos a la base de datos "mi-base-de-datos"
              mongoose.connect('mongodb://localhost/mi-base-de-datos');
            

Para entender cómo usar la librería de Mongoose hay que entender estos dos conceptos

  1. Esquemas (Schemas)
  2. Modelos (Models)

Schemas

El esquema nos sirve para definir los campos, sus características y los tipos de datos de cada recurso que guardaremos en nuestra base de datos

Nos ayuda a castear y validar los datos para evitar incosistencias que puedan producir errores inesperados

Los esquemas se definen con objetos JSON que especifican, para cada campo, su tipo de dato (SchemaType)

  • String
  • Number
  • Date
  • Boolean
  • Array
  • Object
  • ObjectId
  • Otros...

                var mongoose = require('mongoose');
                var Schema = mongoose.Schema;
              
                var blogSchema = new Schema({
                  title:  { 
                    type: String,
                    required: true
                  }
                  author: String,
                  body:   String,
                  comments: [{ body: String, date: Date }],
                  date: { type: Date, default: Date.now },
                  hidden: Boolean,
                  meta: {
                    votes: Number,
                    favs:  Number
                  }
                });              
              

Models

A partir de un esquema podemos producir modelos, que son objetos constructores. Tienen los métodos con los cuales podremos accesar, modificar, insertar o borrar recursos en la base de datos

A partir de un modelo es posible instanciar un nuevo objeto, al que se le conoce como Documento

El constructor de Models de mongoose recibe 2 o 3 parametros

  1. Nombre del Modelo
  2. Esquema
  3. (opcional) Nombre de la colección en la base de datos

                var Blog = mongoose.model('Blog', blogSchema); 
                // collection => 'blogs'  
            

*En caso de no poner el tercer parámetro, por defecto, la colección a usar en la base de datos será el plural (en inglés) del nombre del modelo
Ej. Country => countries

Una ves teniendo el Modelo podemos accesar a la base de datos por medio de los métodos predefinidos

find

              var User = mongoose.model('User', userSchema)

              User.find({name: 'Ralex'}, callback) // versión mas simple

              // con encadenables opcionales
              User.find
              .select // recibe el nombre de los campos a mostrar (1/true) o no (0/false)
              .where // parámetros de búsqueda
              .limit // cuántos documentos a recibir
              .sort // campos según ordenaran acendentemente (1) o descendentemente (0)
              .skip // número de registros a ignorar. Excelente para paginadores
              .exec(callback)
              
              //dentro de los callbacks, cada Documento tiene las funciones
              // - save()  permite iterar y modificar los documentos de la base de datos
              // - delete() permite borrar 
            
Insert

            // Insertar por medio de una instancia
            var User = mongoose.model('User', userSchema)
            let ralex = new User({name: 'Ralex', description: 'Cyber-hippie'})
            ralex.save() // ejecuta la llamada a la base de datos para guardar el documento
            

            // Insertar por medio de una instancia
            var User = mongoose.model('User', userSchema)
            User.create({name: 'Ralex', description: 'Eco-hacker'}, function(err, res) {
              if (err) console.log(err)
              console.log(res)
            })
            

Además de la escrucutra, los esquemas nos permiten definir métodos de instancia, métodos estáticos, índices, ayudadores para consultas e intermediarios para algunos métodos predefinidos

Quiero que Documento instancia del modelo Animal tengan un método para encontar otros animales de su mismo tipo


            animalSchema.methods.findSimilarTypes = function(cb) {
              return this.model('Animal').find({ type: this.type }, cb);
            };
            // ...
            var dog = new Animal({ type: 'dog' });

            dog.findSimilarTypes(function(err, dogs) {
              console.log(dogs); // woof
            });
          

Quiero que mi Modelo Animal tengan un método para encontar por nombre


                animalSchema.statics.findByName = function(name, cb) {
                  return this.find({ name: new RegExp(name, 'i') }, cb);
                };
                var Animal = mongoose.model('Animal', animalSchema);
                Animal.findByName('fido', function(err, animals) {
                  console.log(animals);
                });
              

Para guardar el password de un usuario, no textual, sino hasehado


                let bcrypt = require('bcrypt')
                ...
                userSchema.pre('save', function (user) {
                  user.password = bcrypt.hashSync(user.password)
                })
              

Gracias por su atención

La presentación la pueden encontrar en

ralexrdz.github.io/mongoose-intro

Las tecnologías sobre las cuales fueron grabadas y realizadas la presentación

github.com/ralexrdz/mongoose-intro