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?
$matchFiltrar documentos (como un WHERE en SQL)
$groupAgrupar documentos y calcular valores (sumas, promedios, conteos, etc.)
$projectSeleccionar qué campos mostrar o transformar datos
$sortOrdenar los resultados
$limitLimitar la cantidad de resultados
$lookupUnir 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