9. Agregación de datos

El aggregation pipeline te permite transformar y combinar documentos. Es como hacer un GROUP BY en SQL, pero mucho más potente.

Estructura del pipeline

Una agregación es un array de etapas. Cada etapa transforma los documentos y los pasa a la siguiente:

db.unicorns.aggregate([
    { $match: { ... } },    // Etapa 1: filtrar
    { $group: { ... } },    // Etapa 2: agrupar
    { $sort: { ... } }      // Etapa 3: ordenar
])

Etapa $group

La etapa más importante es $group. Agrupa documentos y calcula valores:

// Contar unicornios por género
db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            total: { $sum: 1 }
        }
    }
])

Resultado:

[
    { _id: 'f', total: 4 },
    { _id: 'm', total: 4 }
]

El campo _id indica por qué campo agrupar. El símbolo $ antes de un nombre de campo significa "el valor de este campo".

Operadores de acumulación

Dentro de $group puedes usar estos operadores:

$sum: suma valores

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            totalWeight: { $sum: '$weight' }
        }
    }
])

$avg: calcula la media

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            avgVampires: { $avg: '$vampires' }
        }
    }
])

$min: valor mínimo

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            minWeight: { $min: '$weight' }
        }
    }
])

$max: valor máximo

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            maxVampires: { $max: '$vampires' }
        }
    }
])

$addToSet: array con valores únicos

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            names: { $addToSet: '$name' }
        }
    }
])

Etapa $match

Filtra documentos antes de agrupar. Es como find:

// Peso medio de unicornios con menos de 600
db.unicorns.aggregate([
    { $match: { weight: { $lt: 600 } } },
    {
        $group: {
            _id: '$gender',
            avgWeight: { $avg: '$weight' }
        }
    }
])

Etapa $sort

Ordena los resultados:

db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            total: { $sum: 1 }
        }
    },
    { $sort: { total: -1 } }
])

Etapa $limit

Limita el número de resultados:

// Top 3 géneros con más unicornios
db.unicorns.aggregate([
    {
        $group: {
            _id: '$gender',
            total: { $sum: 1 }
        }
    },
    { $sort: { total: -1 } },
    { $limit: 3 }
])

Etapa $unwind

Descompone un array en documentos separados. Muy útil para analizar arrays:

// ¿Qué comida es la más popular?
db.unicorns.aggregate([
    { $unwind: '$loves' },
    {
        $group: {
            _id: '$loves',
            count: { $sum: 1 }
        }
    },
    { $sort: { count: -1 } },
    { $limit: 1 }
])

Ejemplo completo

Vamos a encontrar el alimento favorito de los unicornios pesados (más de 500):

db.unicorns.aggregate([
    // 1. Filtra unicornios pesados
    { $match: { weight: { $gt: 500 } } },

    // 2. Descompone el array de comidas
    { $unwind: '$loves' },

    // 3. Agrupa por comida y cuenta
    {
        $group: {
            _id: '$loves',
            total: { $sum: 1 },
            unicorns: { $addToSet: '$name' }
        }
    },

    // 4. Ordena por popularidad
    { $sort: { total: -1 } },

    // 5. Solo el top 1
    { $limit: 1 }
])
Actividad 1
  1. Calcula el número total de listados por barrio (neighbourhood_group_cleansed)
  2. Calcula el número de listados por tipo de habitación (room_type)
  3. Encuentra cuántos superhosts hay en total (cuenta donde host_is_superhost es "t")
  4. Cuenta cuántos listados hay por tipo de propiedad (property_type), muestra solo los 10 más comunes
  5. Calcula cuántos listados tienen más de 50 reseñas

Pro:

  1. Calcula el promedio de accommodates (capacidad) por barrio, ordenado de mayor a menor
  2. Encuentra el top 5 de barrios con más listados (agrupa por neighbourhood_group_cleansed, cuenta y ordena)
  3. Calcula el número máximo de reseñas (number_of_reviews) por cada tipo de habitación (room_type)

Soluciones

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Desafíos de programación atemporales y multiparadigmáticos

Desafíos de programación atemporales y multiparadigmáticos

Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.

Buy the book

Will you buy me a coffee?

Comments

There are no comments yet.

Visitors in real time

You are alone: 🐱