1. Presentación de la práctica
Bienvenidos al Ministerio de las Promesas Imposibles, una institución ficticia donde los políticos registran sus promesas electorales y el presupuesto necesario para cumplirlas.
El problema es que el Ministerio ha perdido el control de sus datos. Hay promesas que se repiten, presupuestos disparatados, proyectos que nadie recuerda haber aprobado y políticos que llevan años prometiendo lo mismo.
El Gobierno ha decidido contratar a un grupo de administradores de sistemas para modernizar la base de datos.
Vuestra misión será construir y gestionar esa base de datos utilizando MongoDB.
A lo largo de la práctica aprenderéis a crear documentos, consultar información, modificar promesas incumplidas y eliminar registros obsoletos.
Todo ello mediante la terminal y sin necesidad de desarrollar una aplicación web.
Objetivos de aprendizaje
Al finalizar, el alumno deberá ser capaz de:
- Comprender qué es MongoDB y en qué se diferencia de MySQL.
- Crear y administrar una base de datos NoSQL.
- Comprender las colecciones y los documentos JSON/BSON.
- Insertar uno o varios documentos.
- Realizar consultas con filtros y operadores.
- Modificar documentos existentes.
- Eliminar registros.
- Realizar consultas sencillas de ordenación y estadísticas.
- Comprender el significado de CRUD.
2. ¿Qué es MongoDB?
MongoDB es una base de datos NoSQL orientada a documentos.
En una base de datos tradicional como MySQL almacenamos información en tablas formadas por filas y columnas. En MongoDB trabajamos con colecciones de documentos que tienen una estructura similar a JSON.
MySQLTablas y filas

MongoDBColecciones y documentos
| MySQL | MongoDB |
|---|---|
| Base de datos | Base de datos |
| Tabla | Colección |
| Fila | Documento |
| Columna | Campo |
| Clave primaria | _id |
| SQL | API de consultas MongoDB |
Por ejemplo, una promesa política podría almacenarse así:
{
"politico": "Pepe Promesas",
"partido": "Partido del Unicornio",
"promesa": "WiFi gratis hasta en los ascensores",
"presupuesto": 250000,
"cumplida": false,
"etiquetas": ["tecnologia", "internet"]
}
Observad que tenemos cadenas de texto, números, valores booleanos y arrays dentro de un mismo documento.
MongoDB almacena los documentos internamente en BSON, una representación binaria que admite tipos adicionales a los de JSON.
3. Preparación del laboratorio
Utilizaremos Docker para no tener que instalar directamente el servidor MongoDB en cada máquina virtual.
Los comandos funcionarán en Linux y también en Windows desde PowerShell, siempre que Docker esté instalado y en ejecución.
Paso 1. Comprobar Docker
Abrimos la terminal y ejecutamos:
docker --version
docker ps
Si Docker está funcionando, podremos consultar la versión y los contenedores activos.
Paso 2. Descargar MongoDB
docker pull mongo:8.0
Usaremos la imagen oficial de MongoDB 8.0, evitando que una actualización automática de latest cambie la versión durante la práctica.
Paso 3. Crear nuestro contenedor
docker run -d \
--name ministerio-mongo \
-v ministerio_datos:/data/db \
mongo:8.0
En este comando:
-dejecuta el contenedor en segundo plano.--nameidentifica nuestro contenedor.-vcrea un volumen persistente para almacenar la base de datos.mongo:8.0es la imagen que estamos utilizando.
Para esta práctica accederemos a MongoDB directamente desde dentro del contenedor. No necesitamos publicar el puerto 27017 ni dejar la base de datos accesible desde la red.
Importante: el servidor se utiliza sin autenticación únicamente dentro de este laboratorio aislado. No es una configuración adecuada para producción.
Paso 4. Comprobar el funcionamiento
docker ps
Deberíamos observar un contenedor llamado ministerio-mongo en estado Up.
Paso 5. Entrar en MongoDB
docker exec -it ministerio-mongo mongosh
Se abrirá la consola interactiva de MongoDB, llamada mongosh.
A partir de ahora, los comandos que escribamos dentro de ella son instrucciones de MongoDB, no comandos Bash.
Podemos comprobar la conexión:
db.runCommand({ ping: 1 })
El resultado debería incluir:
{ "ok": 1 }
Referencia: Documentación de la imagen oficial de MongoDB. Docker Hub+1
4. Crear nuestra primera base de datos
El Ministerio necesita una base de datos donde registrar sus promesas.
Escribimos dentro de mongosh:
use ministerio
Podemos comprobar qué base de datos estamos utilizando:
db.getName()
Resultado:
ministerio
Ahora creamos una colección llamada promesas.
db.createCollection("promesas")
Comprobamos las colecciones:
show collections
Y para visualizar las bases de datos que realmente tienen datos almacenados:
show dbs
Concepto importante: en MongoDB, seleccionar una base de datos con use no significa que ya esté creada físicamente. Se materializa cuando almacenamos información, como al crear nuestra primera colección.
5. CREATE — Insertar documentos
Primera operación CRUD: CREATE
El Ministro de Transformación Digital, Pepe Promesas, ha anunciado su primera medida electoral:
*«Todos los ciudadanos tendrán WiFi gratuito, incluso en los ascensores y en las cuevas». *
Necesitamos registrar esta promesa en nuestra base de datos.
Paso 1. Insertar un documento
db.promesas.insertOne({
politico: "Pepe Promesas",
partido: "Partido del Unicornio",
promesa: "WiFi gratis hasta en los ascensores",
categoria: "Tecnologia",
presupuesto: 250000,
votos: 1200,
cumplida: false
})
El resultado mostrará una confirmación similar a esta:
{
acknowledged: true,
insertedId: ObjectId('...')
}
El campo insertedId contiene el identificador único asignado al documento.
MongoDB genera automáticamente _id cuando no proporcionamos uno.
Paso 2. Insertar varios documentos
El Ministerio acaba de celebrar una reunión extraordinaria. Como era de esperar, han aparecido numerosas promesas nuevas.
Vamos a introducirlas todas de golpe.
db.promesas.insertMany([
{
politico: "Lola Subsidios",
partido: "Union del Bocadillo",
promesa: "Bocadillos gratis todos los viernes",
categoria: "Alimentacion",
presupuesto: 800000,
votos: 4500,
cumplida: false
},
{
politico: "Paco Impuestos",
partido: "Partido del Unicornio",
promesa: "Eliminar todos los impuestos los lunes",
categoria: "Economia",
presupuesto: 5000000,
votos: 9000,
cumplida: false
},
{
politico: "Rosa Aeropuertos",
partido: "Frente de las Rotondas",
promesa: "Construir un aeropuerto en cada pueblo",
categoria: "Infraestructuras",
presupuesto: 15000000,
votos: 3200,
cumplida: false
},
{
politico: "Manolo Digital",
partido: "Union del Bocadillo",
promesa: "Sustituir funcionarios por robots",
categoria: "Tecnologia",
presupuesto: 3000000,
votos: 11000,
cumplida: true
},
{
politico: "Carmen Futuro",
partido: "Frente de las Rotondas",
promesa: "Construir un carril bici hasta la Luna",
categoria: "Infraestructuras",
presupuesto: 50000000,
votos: 1500,
cumplida: false
},
{
politico: "Toni Fiestas",
partido: "Partido del Unicornio",
promesa: "Declarar los lunes festivos",
categoria: "Trabajo",
presupuesto: 2000000,
votos: 18000,
cumplida: true
},
{
politico: "Susana Pantallas",
partido: "Union del Bocadillo",
promesa: "Una pantalla gigante en cada rotonda",
categoria: "Tecnologia",
presupuesto: 650000,
votos: 2700,
cumplida: false
}
])
Ya tenemos ocho promesas electorales registradas, contando la primera.
Paso 3. Contar los documentos
db.promesas.countDocuments({})
Resultado esperado:
8
Comprueba que lo has entendido
¿Qué diferencia existe entre insertOne() e insertMany()? ¿Qué ocurre si ejecutamos dos veces la misma inserción sin especificar un identificador?
La segunda inserción generaría nuevos documentos con identificadores diferentes, creando registros duplicados en cuanto a contenido.
6. READ — Consultar documentos
Segunda operación CRUD: READ
El Ministerio necesita consultar sus promesas. Los políticos empiezan a preguntar qué habían prometido durante la campaña.
Paso 1. Mostrar todas las promesas
db.promesas.find()
El método find() devuelve los documentos de una colección.
También podemos utilizar:
db.promesas.find().toArray()
Esto permite ver los resultados materializados como un array en la consola, algo cómodo para conjuntos pequeños.
Paso 2. Buscar un político concreto
Queremos saber qué prometió Paco Impuestos:
db.promesas.find({
politico: "Paco Impuestos"
})
El resultado será el documento correspondiente a Paco.
Paso 3. Buscar promesas incumplidas
db.promesas.find({
cumplida: false
})
Deberían aparecer seis promesas.
Ahora buscamos las cumplidas:
db.promesas.find({
cumplida: true
})
Deberían aparecer dos.
Paso 4. Consultar por presupuestos
El Tribunal de Cuentas ha solicitado todas las promesas cuyo presupuesto supera un millón de euros.
Utilizaremos el operador $gt, que significa greater than (mayor que).
db.promesas.find({
presupuesto: { $gt: 1000000 }
})
Otros operadores importantes:
| Operador | Significado |
|---|---|
$gt | Mayor que |
$gte | Mayor o igual que |
$lt | Menor que |
$lte | Menor o igual que |
$eq | Igual que |
$ne | Distinto de |
$in | Incluido en una lista |
Paso 5. Combinar condiciones
Queremos conocer las promesas de tecnología que siguen incumplidas.
db.promesas.find({
categoria: "Tecnologia",
cumplida: false
})
Cuando incluimos varias condiciones en un mismo filtro, MongoDB aplica un AND implícito.
En este caso aparecerán las promesas de Pepe Promesas y Susana Pantallas.
Paso 6. Utilizar OR
El Ministerio quiere localizar las promesas que pertenezcan a las categorías de Economía o Trabajo.
db.promesas.find({
$or: [
{ categoria: "Economia" },
{ categoria: "Trabajo" }
]
})
Paso 7. Mostrar solamente algunos campos
No siempre necesitamos visualizar todos los campos de cada documento.
Queremos mostrar solamente el nombre del político, su promesa y el presupuesto.
db.promesas.find(
{},
{
_id: 0,
politico: 1,
promesa: 1,
presupuesto: 1
}
)
El 1 indica que queremos incluir un campo. El 0 indica que deseamos excluirlo.
En este ejemplo también ocultamos _id, que se muestra por defecto.
Paso 8. Ordenar los resultados
Queremos descubrir cuáles son las promesas más caras.
db.promesas.find(
{},
{ _id: 0, politico: 1, presupuesto: 1 }
).sort({ presupuesto: -1 })
En la ordenación:
1significa ascendente.-1significa descendente.
Paso 9. Limitar resultados
El Ministerio solamente quiere las tres promesas más caras.
db.promesas.find(
{},
{ _id: 0, politico: 1, presupuesto: 1 }
).sort({ presupuesto: -1 }).limit(3)
El resultado esperado es:
| Político | Presupuesto |
|---|---|
| Carmen Futuro | 50.000.000 € |
| Rosa Aeropuertos | 15.000.000 € |
| Paco Impuestos | 5.000.000 € |
7. UPDATE — Modificar documentos
Tercera operación CRUD: UPDATE
Han pasado varios meses y el Ministerio necesita actualizar la situación de sus promesas.
Paso 1. Modificar un documento
Pepe Promesas asegura que el WiFi ya funciona en todos los ascensores.
Aunque nadie lo ha podido comprobar, el Ministerio decide marcar la promesa como cumplida.
db.promesas.updateOne(
{ politico: "Pepe Promesas" },
{ $set: { cumplida: true } }
)
El operador $set permite cambiar uno o varios campos.
La respuesta habitual incluye:
matchedCount: 1
modifiedCount: 1
matchedCount indica cuántos documentos coincidieron con el filtro, y modifiedCount cuántos fueron modificados.
Para comprobarlo:
db.promesas.findOne({
politico: "Pepe Promesas"
})
Paso 2. Modificar varios campos
El Gobierno descubre que el carril bici lunar tendrá un coste mayor del previsto.
db.promesas.updateOne(
{ politico: "Carmen Futuro" },
{
$set: {
presupuesto: 75000000,
cumplida: false
}
}
)
Paso 3. Incrementar un valor numérico
Durante una manifestación política, Paco Impuestos ha ganado 500 votos adicionales.
En lugar de consultar los votos actuales y escribir el nuevo total, utilizamos $inc.
db.promesas.updateOne(
{ politico: "Paco Impuestos" },
{ $inc: { votos: 500 } }
)
Si tenía 9.000 votos, ahora tendrá 9.500.
También podemos restar:
db.promesas.updateOne(
{ politico: "Paco Impuestos" },
{ $inc: { votos: -200 } }
)
Ahora tendrá 9.300.
Paso 4. Actualizar varios documentos
El Ministerio decide incrementar en un 10 % el presupuesto de todas las promesas tecnológicas.
db.promesas.updateMany(
{ categoria: "Tecnologia" },
{ $mul: { presupuesto: 1.10 } }
)
updateMany() modifica todos los documentos que cumplan la condición. $mul multiplica el valor numérico por el factor indicado.
Paso 5. Incorporar un campo nuevo
El Ministerio ha creado un departamento de excusas.
Ahora cada promesa necesita un campo llamado excusa.
db.promesas.updateOne(
{ politico: "Rosa Aeropuertos" },
{
$set: {
excusa: "No encontramos suficientes pilotos"
}
}
)
Este campo no existía anteriormente en el documento. MongoDB permite añadirlo sin alterar los demás documentos de la colección.
Este ejemplo ilustra una de las características de MongoDB: su modelo flexible de documentos.
8. DELETE — Eliminar documentos
Cuarta operación CRUD: DELETE
Tras una auditoría interna, el Ministerio decide eliminar algunas promesas de su registro.
Paso 1. Eliminar una promesa
Se ha decidido cancelar el proyecto de las pantallas en las rotondas.
db.promesas.deleteOne({
politico: "Susana Pantallas"
})
El resultado esperado incluye:
deletedCount: 1
Comprobamos que ha desaparecido:
db.promesas.find({
politico: "Susana Pantallas"
})
No debería devolver ningún documento.
Paso 2. Eliminar varios documentos
El Ministerio ha decidido eliminar todas las promesas con presupuestos inferiores a 300.000 €.
Primero consultaremos los documentos afectados:
db.promesas.find({
presupuesto: { $lt: 300000 }
})
En este punto de nuestra práctica, la única promesa que cumple esa condición es la de Pepe Promesas, cuyo presupuesto se incrementó hasta 275.000 €.
Ahora sí, ejecutamos:
db.promesas.deleteMany({
presupuesto: { $lt: 300000 }
})
Advertencia: una operación deleteMany({}) sin filtros eliminaría todos los documentos de la colección. Debemos comprobar siempre la condición antes de ejecutarla.
Paso 3. Comprobar el resultado
db.promesas.countDocuments({})
Si hemos seguido todos los pasos en orden, tendremos seis documentos.
9. Resumen visual de CRUD

10. Consultas adicionales — El escándalo de los presupuestos
Hasta ahora hemos aprendido las cuatro operaciones fundamentales. Pero MongoDB también permite realizar operaciones de análisis.
El Ministerio quiere conocer algunos datos estadísticos sobre sus promesas.
¿Cuánto dinero ha prometido el Gobierno?
Utilizaremos una operación de agregación:
db.promesas.aggregate([
{
$group: {
_id: null,
presupuestoTotal: { $sum: "$presupuesto" }
}
}
])
$group agrupa documentos y $sum suma los valores del campo indicado.
¿Cuántas promesas tiene cada partido?
db.promesas.aggregate([
{
$group: {
_id: "$partido",
totalPromesas: { $sum: 1 }
}
},
{
$sort: { totalPromesas: -1 }
}
])
Esto es una introducción a las aggregation pipelines. No necesitamos profundizar en ellas todavía, pero sí comprender que MongoDB puede hacer algo más que buscar documentos.
11. Reto individual — La campaña electoral del alumno
Misión: Operación Elecciones 404
Actividad autónoma · 30–40 minutos · Sin soluciones
El Ministerio ha decidido convocar nuevas elecciones. Cada alumno deberá crear su propio partido político ficticio y registrar sus promesas absurdas utilizando MongoDB.
Primera parte: creación del partido
El alumno debe crear una nueva colección llamada elecciones.
En ella registrará al menos cinco promesas inventadas por él. Cada documento deberá contener:
- Nombre del político.
- Partido político.
- Promesa electoral.
- Categoría.
- Presupuesto.
- Número de votos.
- Estado de cumplimiento.
- Un campo adicional de su elección.
Los nombres y promesas deben ser ficticios y utilizar el humor o la sátira.
Segunda parte: operaciones obligatorias
Lista de comprobación
0 de 13Crear la colección elecciones.Insertar cinco promesas con insertMany().Mostrar todas las promesas.Buscar las promesas de un partido concreto.Encontrar las promesas cuyo presupuesto supere 1.000.000 €.Mostrar solamente los campos político, promesa y presupuesto.Ordenar las promesas de mayor a menor presupuesto.Mostrar únicamente las dos promesas más votadas.Modificar una promesa para marcarla como cumplida.Incrementar los votos de un político en 1.000.Añadir un campo llamado excusa a un documento.Eliminar una promesa utilizando deleteOne().Mostrar cuántos documentos quedan en la colección.
Reiniciar comprobación
Tercera parte: reto adicional
Los alumnos que terminen antes podrán intentar tres operaciones más sin recibir los comandos directamente:
- Calcular el presupuesto total de todas las promesas.
- Averiguar qué partido tiene más promesas registradas.
- Mostrar únicamente las promesas incumplidas y ordenarlas por número de votos.
12. Entrega del trabajo
El alumno deberá preparar un archivo README.md que incluya una breve explicación de la práctica, los comandos utilizados y las capturas de las operaciones principales.
No es necesario entregar una aplicación web. El objetivo es demostrar que sabe trabajar directamente con MongoDB desde la consola.
Criterios de evaluación
| Apartado | Puntos |
|---|---|
| Creación de BD y colecciones | 1 |
| Inserción de documentos | 2 |
| Consultas y filtros | 3 |
| Actualización de documentos | 2 |
| Eliminación de documentos | 1 |
| Documentación y explicaciones | 1 |
| Total | 10 |
13. Cierre y limpieza del laboratorio
Para salir de la consola de MongoDB:
exit
Ya en la terminal Linux o PowerShell, podemos detener el contenedor:
docker stop ministerio-mongo
Para volver a utilizarlo otro día:
docker start ministerio-mongo
docker exec -it ministerio-mongo mongosh
Gracias al volumen ministerio_datos, nuestra información seguirá almacenada aunque detengamos el contenedor.
Si queremos eliminar el contenedor al terminar:
docker rm -f ministerio-mongo
El volumen seguirá existiendo. Para eliminar también todos los datos, de forma irreversible:
docker volume rm ministerio_datos
14. Preguntas finales para reflexionar
Antes de entregar, cada alumno deberá contestar brevemente:
- ¿Qué diferencia existe entre una tabla de MySQL y una colección de MongoDB?
- ¿Para qué sirve el campo
_id? - ¿Qué diferencia hay entre
find()yfindOne()? - ¿Cuándo utilizarías
updateOne()en lugar deupdateMany()? - ¿Qué ocurriría si ejecutases
deleteMany({})? - ¿Por qué puede resultar útil que dos documentos de una colección tengan campos diferentes?
- ¿Para qué nos sirve utilizar un volumen Docker en esta práctica?


















