Skip to content

Latest commit

 

History

History
315 lines (274 loc) · 11.1 KB

README.md

File metadata and controls

315 lines (274 loc) · 11.1 KB

MongoDB

Pre-requisitos de la sesión en vivo

  • Tener instalado Docker
  • En caso de no tener instalado Docker, tener instalado MongoDB
  • Revisar los conceptos básicos:

Temario

SQL vs NoSQL

Referencias:

Conceptos básicos

Documentos y colecciones en español

Primeros pasos

Referencias

Comandos

  • Levantar instancia de MongoDB docker run --name mongodb -d mongo
  • Conectarse a MongoDB docker exec -it mongodb mongosh
  • Mostrar bases de datos show dbs
  • Crear / Usar base de datos use wizeline_baz_db
  • Mostrar base de datos en uso db
  • Insertar documentos
    • Insertar un documento db.proyecto.insertOne({"nombre":"workshop"})

    • Insertar multiples documentos db.proyectos.insertMany([ { nombre: "Proyecto multiple", responsables: ["CTO", "TL"], tipo: "multiple" }, { nombre: "Proyecto cancelado" }])

Operaciones CRUD

Referencia: Operaciones CRUD

  • Consultar documentos
    • Consultar sin filtros db.proyectos.find()

    • Consultar con filtros

db.proyectos.find({"cantidad": 1, "tipo": "single"})
db.proyectos.find({$or: [{"cantidad": 1}, {"tipo": "multiple"}]})
  • Actualizar documentos
    • Actualizar un documento
db.proyectos.updateOne({ cantidad: 1 }, { $set: { tipo: "prueba" } })
  • Actualizar multiples documentos
db.proyectos.updateMany( { presupuesto: { $ne: 100 } }, { $set: { presupuesto: 100 } })
  • Eliminar documentos
    • Eliminar todos los documentos db.proyectos.deleteMany({})

    • Eliminar documentos filtrados db.proyectos.deleteMany({ cantidad: 1 })

Aggregation Pipeline

Primero creamos una nueva DB por nombre BAZ-Project

Crearemos una colección por nombre employees y agregaremos los siguientes registros

db.employees.insertMany([
    { 
        _id:1,
        firstName: "John",
        lastName: "King",
        gender:'male',
        email: "[email protected]",
        salary: 5000,
        department: { 
                    "name":"HR" 
                }
    },
    { 
        _id:2,
        firstName: "Sachin",
        lastName: "T",
        gender:'male',
        email: "[email protected]",
        salary: 8000,
        department: { 
                    "name":"Finance" 
                }
    },
    { 
        _id:3,
        firstName: "James",
        lastName: "Bond",
        gender:'male',
        email: "[email protected]",
        salary: 7500,
        department: { 
                    "name":"Marketing" 
                }
    },
    { 
        _id:4,
        firstName: "Rosy",
        lastName: "Brown",
        gender:'female',
        email: "[email protected]",
        salary: 5000, 
        department: { 
                    "name":"HR" 
                }

    },
    { 
        _id:5,
        firstName: "Kapil",
        lastName: "D",
        gender:'male',
        email: "[email protected]",
        salary: 4500,
        department: { 
                    "name":"Finance" 
                }

    },
    { 
        _id:6,
        firstName: "Amitabh",
        lastName: "B",
        gender:'male',
        email: "[email protected]",
        salary: 7000,
        department: { 
                    "name":"Marketing" 
                }
    }
])

Uso de $match Stage

$match es usado principalmente para seleccionar solo los documentos que hagan match dentro de una colección. Equivalente al metodo find().

db.employees.aggregate([ {$match:{ gender: 'female'}} ])

Uso de $group Stage

$group se usa para agrupar los documentos que sean especificados por el _id y devuelve un solo documento que contiene valores acumulados para cada grupo distinto.

// El campo $grouputiliza _idpara calcular los valores acumulados de todos los documentos de entrada en su conjunto. La expresión { _id:'$department.name'}crea el grupo diferenciado en el campo $department.name. Como no calculamos ningún valor acumulado, devuelve los distintos valores de $department.name, como se muestra a continuación.
db.employees.aggregate([ 
    { $group:{ _id:'$department.name'} }
])

// Calculemos los valores acumulados para cada grupo. Ej. calcular el número de empleados en cada departamento
db.employees.aggregate([ 
    { $group:{ _id:'$department.name', totalEmployees: { $sum:1 } } 
}])

La siguiente pipeline de agregación contiene dos etapas:

db.employees.aggregate([ 
    { $match:{ gender:'male'}}, 
    { $group:{ _id:'$department.name', totalEmployees: { $sum:1 } } 
}])

En el ejemplo anterior, la primera etapa selecciona a todos los empleados varones y los pasa como entrada a la segunda etapa $groupcomo entrada. Entonces, la salida calcula la suma de todos los empleados varones.

Calcular la suma de los salarios de todos los empleados varones en el mismo departamento.

db.employees.aggregate([ 
    { $match:{ gender:'male'}}, 
    { $group:{ _id:{ deptName:'$department.name'}, totalSalaries: { $sum:'$salary'} } 
}])

En el ejemplo anterior, { $match:{ gender:'male'}} devuelve todos los empleados varones. En la $group stage, tenemos una expresión de acumulador totalSalaries: { $sum:'$salary'} suma el campo numérico salary y lo incluye como totalSalaries en la salida de cada grupo.

Uso de $sort Stage

El $sort stage se usa para clasificar los documentos según el campo especificado en orden ascendente o descendente.

db.employees.aggregate([
    { $match:{ gender:'male'}}, 
    { $sort:{ firstName:1}}
])

En el ejemplo anterior, el $match stage devuelve todos los empleados masculinos y pasa a la siguiente etapa $sort. La { $sort:{ firstName:1}} expresión ordena los documentos de entrada por firstName campo en orden ascendente. El 1 indica el orden ascendente y -1 indica el orden descendente.

La siguiente pipeline contiene tres etapas para ordenar los documentos agrupados:

 db.employees.aggregate([
    { $match:{ gender:'male'}}, 
    { $group:{ _id:{ deptName:'$department.name'}, totalEmployees: { $sum:1} } },
    { $sort:{ deptName:1}}
])

Por lo tanto, puede usar el aggregation pipeline para obtener los documentos requeridos de la colección.

Ejercicio de Aggregation Pipeline

Tomando como base el archivo aggregation_excercise.json e importandolo y creando la colección de Movies dentro de la base de datos, contesta lo siguiente:

1. Encuentra la pelicula con el rate mas alto por cada director
2. Encuentra el numero de peliculas dirijidas por cada director
3. Encuentra la pelicula con el rating mas alto, donde Ricky sea el director y Tom Hanks sea uno de los actores.
4. ¿Cuantas peliculas protagonizo Tom Hanks?
5. Muestra la lista de todos los actores que trabajaron con el director Jon What.

Schema Validation

Creación de una colección de Usuarios, agregando un schema validation

db.createCollection( "users" , { 
   validator: { $jsonSchema: { 
      bsonType: "object", 
      required: [ "name", "surname", "email" ], 
      properties: { 
         name: { 
            bsonType: "string", 
            description: "required and must be a string" }, 
         surname: { 
            bsonType: "string", 
            description: "required and must be a string" }, 
         email: { 
            bsonType: "string", 
            pattern: "^.+\@.+$", 
            description: "required and must be a valid email address" }, 
         year_of_birth: { 
            bsonType: "int", 
            minimum: 1900, 
            maximum: 2018,
            description: "the value must be in the range 1900-2018" }, 
         gender: { 
            enum: [ "M", "F" ], 
            description: "can be only M or F" } 
      }
   }
}})

Agregar una validación de schema a una colección previamente creada

db.runCommand( { collMod: "Contacts", 
   validator: { 
      $jsonSchema : { 
         bsonType: "object", 
         required: [ "name", "phone", "email", "gender" ], 
         properties: { 
            name: { 
               bsonType: "string", 
               description: "required and must be a string" }, 
            phone: { 
               bsonType: "string", 
               description: "required and must be a string" }, 
           email: { 
               bsonType: "string", 
               pattern: "^.+\@.+$", 
               description: "required and must be a valid email address" }, 
           gender: { 
               enum: [ "M", "F", "T" ], 
               description: "required and must be M, F, T" } 
          }
       }
}, 
validationLevel: "moderate", 
validationAction: "warn" 
})

Las dos nuevas opciones validationLevel y validationAction son importantes en este caso.

ValidationLevel puede tener los siguientes valores:

  • off : no se aplica la validación
  • strict: es el valor por defecto. La validación se aplica a todas las inserciones y actualizaciones
  • moderado: la validación se aplica a todos los documentos válidos existentes. Los documentos no válidos se ignoran.

Al crear reglas de validación en colecciones existentes, el valor "moderado" es la opción más segura.

ValidationAction puede tener los siguientes valores:

  • error: es el valor por defecto. El documento debe pasar la validación para ser escrito
  • warn: se escribe un documento que no pasa la validación pero se registra un mensaje de advertencia

Al agregar reglas de validación a una colección existente, la opción más segura es "advertir"

Estas dos opciones se pueden aplicar incluso con createCollection. No los usamos porque los valores predeterminados son buenos en la mayoría de los casos.

Modelos y esquemas

Referencia: MongoDB Arquitectura y modelo de datos

Índices

Referencia: MongoDB: creación y utilización de índices

Hashing

Referencia: dbHash

Replica Set

Referencia: Replication

Mejores Practicas de Diseño

Referencia: Diseño