1. Introducción
En el siguiente post instalaremos MongoDB en Docker. Crearemos una base de datos, una colección, insertaremos datos de prueba y haremos uso de las funciones find
y aggregation
para extraer información.
2. Instalación en Docker
La instalación de MongoDB la haremos sobre Docker haciendo uso de docker-compose. Si no tienes Docker instalado, podrás ver cómo harcerlo en el post SpringBoot – Docker.
El nombre de nuestro contenedor será my-mongodb
Arrancamos nuestro contenedor docker a través de docker-compose
3. Creación BD, colección e inserción de datos
Arrancamos el cliente mongo que se encuentra dentro de nuestra imagen docker
Usando el comando use
seleccionamos la base de datos con la que vamos a trabajar. Si no existe se crea.
Creamos la colección user
Insertamos los siguientes documentos en nuestra colección user.
db.user.insert({"_id":"1","name":"admin","surname":"admin","gender":"male","roles":["ROLE_ADMIN"]}) db.user.insert({"_id":"2","name":"Jorge","surname":"HernándezRamírez","gender":"male","roles":["ROLE_ADMIN"],"teams":[{"name":"UD.LasPalmas","sport":"Football"},{"name":"RealMadrid","sport":"Football"},{"name":"McLaren","sport":"F1"}]}) db.user.insert({"_id":"3","name":"Jose","gender":"male","surname":"HernándezRamírez","roles":["ROLE_USER"],"teams":[{"name":"UD.LasPalmas","sport":"Football"},{"name":"MagnusCarlsen","sport":"Chess"}]}) db.user.insert({"_id":"4","name":"Raul","surname":"GonzálezBlanco","gender":"male","roles":["ROLE_USER"],"teams":[{"name":"RealMadrid","sport":"Football"},{"name":"RealMadrid","sport":"Basketball"}]}) db.user.insert({"_id":"5","name":"Constanza","surname":"RamírezRodríguez","gender":"female","roles":["ROLE_USER"],"teams":[{"name":"UD.LasPalmas","sport":"Football"}]})
4. Find
1. Obtener todos los documentos
Resultado
{ "_id" : "1", "name" : "admin", "surname" : "admin", "gender" : "male", "roles" : [ "ROLE_ADMIN" ] } { "_id" : "2", "name" : "Jorge", "surname" : "Hernández Ramírez", "gender" : "male", "roles" : [ "ROLE_ADMIN" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" }, { "name" : "Real Madrid", "sport" : "Football" }, { "name" : "McLaren", "sport" : "F1" } ] } { "_id" : "3", "name" : "Jose", "gender" : "male", "surname" : "Hernández Ramírez", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" }, { "name" : "Magnus Carlsen", "sport" : "Chess" } ] } { "_id" : "4", "name" : "Raul", "surname" : "González Blanco", "gender" : "male", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "Real Madrid", "sport" : "Football" }, { "name" : "Real Madrid", "sport" : "Basketball" } ] } { "_id" : "5", "name" : "Constanza", "surname" : "Ramírez Rodríguez", "gender" : "female", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" } ] }
2. Obtener los documentos cuyo atributo gender tenga al valor male. No mostrar los atributos _id, surname, gender, roles y teams
Resultado
3. Mostrar documentos que contengan como equipo a la UD. Las Palmas.
o bien utilizando $in
Resultado
{ "_id" : "2", "name" : "Jorge", "surname" : "Hernández Ramírez", "gender" : "male", "roles" : [ "ROLE_ADMIN" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" }, { "name" : "Real Madrid", "sport" : "Football" }, { "name" : "McLaren", "sport" : "F1" } ] } { "_id" : "3", "name" : "Jose", "gender" : "male", "surname" : "Hernández Ramírez", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" }, { "name" : "Magnus Carlsen", "sport" : "Chess" } ] } { "_id" : "5", "name" : "Constanza", "surname" : "Ramírez Rodríguez", "gender" : "female", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" } ] }
4. Mostrar aquellos usuarios que sigan a la UD. Las Palmas y a Magnus Carlsen.
o bien
Resultado
{ "_id" : "3", "name" : "Jose", "gender" : "male", "surname" : "Hernández Ramírez", "roles" : [ "ROLE_USER" ], "teams" : [ { "name" : "UD. Las Palmas", "sport" : "Football" }, { "name" : "Magnus Carlsen", "sport" : "Chess" } ] }
5. Contar los documentos que tengan el rol ‘ROLE_ADMIN’
Resultado
4. Aggregate
Las agregaciones las utilizamos para realizar operaciones de agrupación de datos, conteo, sumas etc. Es el análogo al group by
en las bases de datos relacionales.
1. Obtener el número de hombres y mujeres del sistema.
Resultado
2. Obtener el número de usuarios en los que el Real Madrid es su equipo.
db.user.aggregate( {$match: {"teams.name": "Real Madrid"}}, {$group: {_id: null, count: {$sum: 1}} })
Resultado
3. Unwind.
$unwind
es el análogo a hacer un join en sql. Deconstruye el array permitiendo obtener tantos documentos diferentes como elementos existen.
Resultado
{ "_id" : "2", "name" : "Jorge", "surname" : "Hernández Ramírez", "gender" : "male", "roles" : [ "ROLE_ADMIN" ], "teams" : { "name" : "Real Madrid", "sport" : "Football" } } { "_id" : "4", "name" : "Raul", "surname" : "González Blanco", "gender" : "male", "roles" : [ "ROLE_USER" ], "teams" : { "name" : "Real Madrid", "sport" : "Football" } } { "_id" : "4", "name" : "Raul", "surname" : "González Blanco", "gender" : "male", "roles" : [ "ROLE_USER" ], "teams" : { "name" : "Real Madrid", "sport" : "Basketball" } }
4. Obtener el número de veces que el Real Madrid es un equipo de un usuario.
db.user.aggregate( {$unwind: "$teams"}, {$match: {"teams.name": "Real Madrid"}}, {$group: {_id: null, count: {$sum: 1}}} )
Resultado
5. $last, $addToSet
-
$last
nos permite obtener el último elementos encontrado al hacer el groupby. -
$addToSet
nos permite obtener una lista de un atributo de los documentos que intervienen en el groupby.
db.user.aggregate( {$group: {_id: "$gender", count : {$sum : 1}, lastName: {$last: "$name"}, nameList: {$addToSet: "$name"}}}, {$project: {_id: 0}})
Resultado