Bases de datos nosql
1. ¿Qué es una agregación?
Las consultas normales (find()) nos permiten buscar datos, pero las agregaciones permiten hacer análisis avanzado, como contar registros, calcular promedios, sumar valores, etc.
📌 Ejemplo:
Queremos saber el precio promedio de todos los productos en nuestra base de datos.
✔️ Con una consulta normal (find()), obtenemos todos los productos:
1db.productos.find()
✔️ Con una agregación, podemos calcular el precio promedio:
1db.productos.aggregate([ 2 { $group: { _id: null, precioPromedio: { $avg: "$precio" } } } 3])
✅ Resultado:
1[ 2 { "precioPromedio": 950 } 3]
Conclusión: La agregación nos devuelve información procesada sin necesidad de trabajar los datos fuera de la base.
2. El Pipeline de Agregación
Una agregación en MongoDB se compone de varias etapas (como una tubería que procesa datos paso a paso).
📌 Las etapas más usadas:
| Etapa | ¿Para qué sirve? |
|---|---|
$match | Filtrar documentos (como un WHERE en SQL) |
$group | Agrupar documentos y calcular valores (sumas, promedios, conteos, etc.) |
$project | Seleccionar qué campos mostrar o transformar datos |
$sort | Ordenar los resultados |
$limit | Limitar la cantidad de resultados |
$lookup | Unir datos de otra colección (similar a un JOIN en SQL) |
3. Ejemplo Práctico: Análisis de Productos
Imaginemos que tenemos una colección de productos con esta estructura:
1[ 2 { "nombre": "Laptop", "marca": "Dell", "precio": 1200, "stock": 5 }, 3 { "nombre": "Celular", "marca": "Samsung", "precio": 800, "stock": 10 }, 4 { "nombre": "Tablet", "marca": "Apple", "precio": 1000, "stock": 3 } 5]
🔹 Filtrar productos con $match
Queremos ver solo los productos con precio mayor a 900:
1db.productos.aggregate([ 2 { $match: { precio: { $gt: 900 } } } 3])
✅ Resultado:
1[ 2 { "nombre": "Laptop", "marca": "Dell", "precio": 1200 }, 3 { "nombre": "Tablet", "marca": "Apple", "precio": 1000 } 4]
🔹 Agrupar productos por marca con $group
Queremos saber cuántos productos hay de cada marca:
1db.productos.aggregate([ 2 { $group: { _id: "$marca", cantidad: { $sum: 1 } } } 3])
✅ Resultado:
1[ 2 { "_id": "Dell", "cantidad": 1 }, 3 { "_id": "Samsung", "cantidad": 1 }, 4 { "_id": "Apple", "cantidad": 1 } 5]
🔹 Calcular el precio promedio de los productos con $group
1db.productos.aggregate([ 2 { $group: { _id: null, precioPromedio: { $avg: "$precio" } } } 3])
✅ Resultado:
1[ 2 { "precioPromedio": 1000 } 3]
🔹 Seleccionar solo algunos campos con $project
Si solo queremos ver el nombre y el precio de los productos:
1db.productos.aggregate([ 2 { $project: { _id: 0, nombre: 1, precio: 1 } } 3])
✅ Resultado:
1[ 2 { "nombre": "Laptop", "precio": 1200 }, 3 { "nombre": "Celular", "precio": 800 }, 4 { "nombre": "Tablet", "precio": 1000 } 5]
🔹 Ordenar productos por precio con $sort
Para mostrar los productos del más barato al más caro:
1db.productos.aggregate([ 2 { $sort: { precio: 1 } } 3])
✅ Resultado:
1[ 2 { "nombre": "Celular", "precio": 800 }, 3 { "nombre": "Tablet", "precio": 1000 }, 4 { "nombre": "Laptop", "precio": 1200 } 5]
🔹 Limitar la cantidad de resultados con $limit
Si solo queremos ver los 2 productos más baratos:
1db.productos.aggregate([ 2 { $sort: { precio: 1 } }, 3 { $limit: 2 } 4])
✅ Resultado:
1[ 2 { "nombre": "Celular", "precio": 800 }, 3 { "nombre": "Tablet", "precio": 1000 } 4]
🔹 Unir información con $lookup (JOIN en NoSQL)
Si tenemos una colección de pedidos y queremos ver los detalles del producto en cada pedido, usamos $lookup.
Ejemplo: Colección pedidos
1[ 2 { "_id": 1, "producto_id": "Laptop", "cantidad": 2 }, 3 { "_id": 2, "producto_id": "Celular", "cantidad": 1 } 4]
Consulta para unir pedidos con productos
1db.pedidos.aggregate([ 2 { 3 $lookup: { 4 from: "productos", 5 localField: "producto_id", 6 foreignField: "nombre", 7 as: "productoDetalles" 8 } 9 } 10])
✅ Resultado:
1[ 2 { "_id": 1, "producto_id": "Laptop", "cantidad": 2, "productoDetalles": [{ "marca": "Dell", "precio": 1200 }] }, 3 { "_id": 2, "producto_id": "Celular", "cantidad": 1, "productoDetalles": [{ "marca": "Samsung", "precio": 800 }] } 4]
📌 Así podemos hacer un "JOIN" en bases documentales.
6. ¿Por qué usar agregaciones?
✅ Permiten procesar grandes volúmenes de datos sin necesidad de traer todo al código
✅ Mejoran el rendimiento y evitan consultas innecesarias
✅ Facilitan el análisis de datos directamente en la base de datos