El fin de esta entrada, no es más que el de proporcionar al lector una muy breve introducción sobre la base de datos MongoDB así como el facilitar una serie de consultas recurrentes para agilizar los procesos de obtención/edición de datos sobre colecciones Mongo ya creadas.
Contexto NoSQL
Antes de nada, estaría bien conocer que a parte de MongoDB existen algunas implementaciones similares que en el mercado como podrían ser Redis, Cassandra, Riak, Azure Cosmos DB, cloud Firestore, Amazon DynamoDB…
Al final todas tienen en común los siguientes puntos más importantes:
- Son bases de datos NoSQL, es decir, son no relacionales entre sus elementos (no se agrupan por tablas, por claves…).
- Proporcionar flexibilidad para guardar y recuperar la información (los esquemas no son fijos).
- Permite escalar el sistema para almacenar grandes cantidades de datos.
Por la manera en la que se guardan o agrupan los datos en las distintas BD NoSQL, decir, que existen diversos estándares entre los cuales los más populares son: por clave-valor, Gráficos o documentos.
Concretamente MongoDB es una base de datos NoSQL open source orientada a almacenar documentos en formato JSON (BSON) en colecciones.
Como ejemplo de lo que consideraríamos un registro en la BD, nos podemos encontrar con el siguiente documento:
Al final la idea es tener una llave de apertura y cierre con los nombres de los elementos y sus valores. Estos valores pueden ser del tipo que más se adapte a nuestras necesidades (números, texto, imágenes, arreglos, documentos…)
Instalación MongoDB en Windows
Sin detenernos en exceso en este apartado, para instalar Mongo solo debemos irnos al enlace de la página principal de Mongo y descargarnos la versión gratuita community Server para la última versión disponible y el sistema operativo utilizado.
En este paso ejecutamos el instalador y seleccionamos las preferencias que necesitemos.
Al final de la instalación, abrimos el cmd y ejecutamos el comando: Mongod -version para comprobar que tenemos instalada la BD .
Si no les funciona el comando, diríjanse al editor de variables de entorno, añadan en el apartado «Path» la ruta de instalación de Mongo y reinicien el equipo y/o la consola
Gestor gráfico:
Entre las opciones de instalación de Mongo, nos encontramos una opción para instalar el gestor Mongo Compass, pero aunque desde Mongo nos recomiendan su uso y tiene muchas funcionalidades interesantes, en nuestro caso recomendamos alternarlo con el uso de Robo3T (en esta entrada haremos uso de este) que nos parece más liviano y quizás intuitivamente más sencillo de utilizar para las operaciones que aquí se explicarán.
Introducción a sentencias MongoDB
BD y Colección:
Antes de empezar, indicar que con el fin de hacer este post más ameno y visual, vamos a ejecutar algunas de las sentencias desde el gestor, pero podéis ir ejecutando las sentencias de igual modo desde la consola conectándoos primero con Mongod, a la conexión, BD y conexiones indicadas.
Una vez tengamos ya nuestra conexión disponible (en nuestro caso la conexión la vamos a identificar como APOLO_DEMO), tenemos que crear una BD la vamos a llamar APOLO:
Para crear la BD desde la consola solo ejecutaremos el comando:
> use APOLO
Dentro de esta BD vamos a crear una colección llamada ALUMNOS:
Para crear la colección desde la consola solo ejecutaremos un comando de inserción de registros y aunque no exista dicha colección, la insertará:
db.personas.insert({…})
Simple CRUD:
Vamos a insertar de primeras los registros que muestro a continuación:
db.getCollection('ALUMNOS').insertMany([
{"nombre" : "Antonio Carlos", apellidos" : "Moruno", "edad": 10, "nota" : 4, absentismo":true, asignaturas" : [ {"asignaturaId" : 1,"nombre" : "Mates","notaAsignatura" : 1},{"asignaturaId" : 2,"nombre" : "Lengua","notaAsignatura" : 5}] },
{"nombre" : "Ruud", apellidos" : "Gullit", "edad": 14, "nota" : 3, absentismo":true, asignaturas" : [ {"asignaturaId" : 1,"nombre" : "Mates","notaAsignatura" : 6},{"asignaturaId" : 2,"nombre" : "Lengua","notaAsignatura" : 8}] },
{"nombre" : "Raúl", apellidos" : "Gónzalez", "edad": 8, "nota" : 5, absentismo":true, asignaturas" : [ {"asignaturaId" : 1,"nombre" : "Mates","notaAsignatura" : 5},{"asignaturaId" : 2,"nombre" : "Lengua","notaAsignatura" : 4}] },
{"nombre" : "Zinedin", apellidos" : "Zidane", "edad": 25, "nota" : 0, absentismo":false, asignaturas" : [ {"asignaturaId" : 1,"nombre" : "Mates","notaAsignatura" : 0},{"asignaturaId" : 2,"nombre" : "Lengua","notaAsignatura" : 0}]}
])
En este apartado veremos de forma sencilla las sentencias CRUD más comunes.
- Inserts de registros simple o compuesto:
db.getCollection('ALUMNOS').insertOne({'nombre':'Manuel', 'apellidos':'Moruno'})
db.getCollection('ALUMNOS').insertMany([{'nombre':'Jorge', 'apellidos':'Miranda'}, {'nombre':'Joaquín', 'apellidos':'Calle'}])
- Búsquedas de registros recurrentes:
- Actualización de registros:
db.getCollection('ALUMNOS').updateOne({'_id':ObjectId('62bae13ab0379d21702fc85d')}, {$set: {'nombre':'Juan'}})
En este caso editaríamos a todas las personas que se llamasen Manuel por Manu:
db.getCollection('ALUMNOS').updateMany({'nombre':'Manuel'}, {$set: {'nombre':'Manu'}})
- Borrado de registros:
db.getCollection('ALUMNOS').deleteOne({'_id':ObjectId('62bae13ab0379d21702fc85d')})
En este caso borraríamos a todas las personas que se llamasen Manu:
db.getCollection('ALUMNOS').deleteMany({'nombre':'Manu'}, {$set: {'nombre':'Manu'}})
Consultas recurrentes:
Para terminar, en este apartado vamos a ver posibles sentencias a las que podemos recurrir cuando queremos localizar y/o actualizar registros de una manera más concreta.
- IN/ NOT IN:
db.getCollection('ALUMNOS').find({'edad':{$in: [ 8, 9 ]}})
db.getCollection('ALUMNOS').find({'edad':{$nin: [ 8, 9 ]}})
- != (DISTINTO A..):
db.getCollection('ALUMNOS').find({'edad':{$ne: 10}})
- X > 50 (MAYOR QUE..):
db.getCollection('ALUMNOS').find({'edad':{$gt: 50}})
- X >= 50 (MAYOR O IGUAL QUE..):
db.getCollection('ALUMNOS').find({'edad':{$gte: 50}})
- X < 50 (MENOR QUE…):
db.getCollection('ALUMNOS').find({'edad':{$lt: 50}})
- X <= 50 (MENOR O IGUAL QUE…):
db.getCollection('ALUMNOS').find({'edad':{$lte: 50}})
- AND | OR:
db.getCollection('ALUMNOS').find( {$and: [{ $or: [ { 'edad': { $lt : 10 } }, { 'edad': { $gt: 50 } } ] },{ $or: [ { 'absentismo': true }, { 'nota': { $lt : 5 } } ] }]} )
- Distinct
db.getCollection('ALUMNOS').distinct("nombre")
- Distinct con where:
db.getCollection('ALUMNOS').distinct("nombre",{'nota':10})
- orden (-1 desc; 1 asc):
db.getCollection('ALUMNOS').find({}).sort( { "_id": -1 } )
- Group by:
db.getCollection('ALUMNOS').aggregate([{$group:{_id : "$nombre", total:{$sum:1}}}]);
Ejemplos más complejos de filtros y ejecuciones:
- Ej (1). Recorre todos los documentos e inserta en cada uno un numero random en el campo nota:
db.getCollection('ALUMNOS').find({}).forEach(function(doc) {db.getCollection('ALUMNOS').update({ _id: doc._id }, {$set: {"nota":NumberInt(Math.floor((Math.random()*(0 - 10)) + 10))}},false,true)})
- Ej (2). Muestra el nombre y la asignatura matemáticas del array de asignaturas de todos los alumnos que tengan en la asignatura de matemáticas menos de un 5.
db.getCollection('ALUMNOS').find(
{asignaturas:{$elemMatch:{asignaturaId : 1, notaAsignatura:{ $eq: 0 }}}},
{_id:0, nombre:1,asignaturas:{$elemMatch:{asignaturaId:1}}}
).toArray();
- Ej (3). Copiar de una tabla a otra «n» documentos
var copy = db.getCollection('ALUMNOS').find({})
for (var i = 0; i< 300; i++){
db.getCollection('ALUMNOS_COPY').insert(copy);
}