- Tener instalado Docker
- En caso de no tener instalado Docker, tener instalado MongoDB
- Revisar los conceptos básicos:
Referencias:
- Documentos
- Colecciones
Documentos y colecciones en español
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" }])
-
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 })
-
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"
}
}
])
$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'}} ])
$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.
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.
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.
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ónstrict
: es el valor por defecto. La validación se aplica a todas las inserciones y actualizacionesmoderado
: 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 escritowarn
: 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.
Referencia: MongoDB Arquitectura y modelo de datos
Referencia: MongoDB: creación y utilización de índices
Referencia: dbHash
Referencia: Replication
Referencia: Diseño