Configurar agregaciones métricas y de buckets para KPIs

Lectura
20 min~6 min lectura

Concepto clave

Las agregaciones en Elasticsearch son el mecanismo principal para transformar datos brutos en KPIs (Indicadores Clave de Rendimiento) procesables. Piensa en ellas como el equivalente a las funciones de resumen en Excel (SUM, AVG, COUNT), pero ejecutándose en tiempo real sobre millones de documentos distribuidos. Mientras que una búsqueda responde "¿qué documentos coinciden con mi consulta?", una agregación responde "¿qué patrones, tendencias o estadísticas emergen de esos documentos?".

Existen dos tipos fundamentales: las agregaciones métricas (que calculan valores numéricos como promedios, sumas, máximos o percentiles) y las agregaciones de buckets (que agrupan documentos en categorías, como rangos de fechas, intervalos de precios o términos únicos). La potencia real surge al combinarlas: por ejemplo, agrupar ventas por región (bucket) y luego calcular el promedio de valor por transacción dentro de cada región (métrica). Esto permite construir dashboards que respondan preguntas como "¿Cuál es el ingreso promedio por cliente en cada país durante el último trimestre?" en segundos.

Cómo funciona en la práctica

Imagina un índice de Elasticsearch llamado ventas_ecommerce que contiene documentos con este mapeo simplificado:

{
  "producto": "text",
  "categoria": "keyword",
  "precio": "float",
  "fecha_venta": "date",
  "region": "keyword",
  "cliente_id": "keyword"
}

Para calcular KPIs comunes, construirías una solicitud de agregación dentro del cuerpo de una búsqueda. Por ejemplo, para obtener el total de ventas y el precio promedio por categoría en la región "Norte" durante el último mes:

GET /ventas_ecommerce/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        { "term": { "region": "Norte" } },
        { "range": { "fecha_venta": { "gte": "now-1M" } } }
      ]
    }
  },
  "aggs": {
    "ventas_por_categoria": {
      "terms": { "field": "categoria" },
      "aggs": {
        "total_ventas": { "sum": { "field": "precio" } },
        "precio_promedio": { "avg": { "field": "precio" } }
      }
    }
  }
}

La respuesta incluirá buckets para cada categoría, cada uno con las métricas calculadas. Esto se puede visualizar directamente en Kibana como un gráfico de barras con valores superpuestos.

Caso de estudio

Una plataforma de streaming necesita monitorizar el engagement de los usuarios. Tienen un índice logs_reproducciones con campos como usuario_id, contenido_id, duracion_vista (en minutos), timestamp, y dispositivo. Los KPIs requeridos son: 1) Número total de reproducciones por día, 2) Duración total vista por tipo de dispositivo, 3) Los 10 contenidos más vistos en la última semana.

La agregación combinada para el KPI 2 sería:

GET /logs_reproducciones/_search
{
  "size": 0,
  "query": { "range": { "timestamp": { "gte": "now-7d" } } },
  "aggs": {
    "por_dispositivo": {
      "terms": { "field": "dispositivo" },
      "aggs": {
        "duracion_total": { "sum": { "field": "duracion_vista" } }
      }
    }
  }
}

Para el KPI 3, se usaría una agregación de términos en contenido_id con un orden descendente por el recuento de documentos, limitado a 10. Estos resultados alimentan un dashboard de Kibana que actualiza en tiempo real, permitiendo al equipo de contenido tomar decisiones basadas en datos frescos.

Errores comunes

  • Usar campos de tipo text para agregaciones de buckets: Los campos text están analizados (divididos en tokens), lo que hace que las agregaciones por términos sean impredecibles. Siempre usa campos keyword para agrupar por valores exactos, o define un subcampo keyword en el mapeo.
  • Ignorar el impacto en el rendimiento con cardinalidad alta: Agrupar por campos con miles de valores únicos (como usuario_id) puede consumir mucha memoria. Usa el parámetro size para limitar el número de buckets devueltos, o considera agregaciones como cardinality para estimaciones.
  • No filtrar datos antes de agregar: Ejecutar agregaciones sobre todo el índice sin una consulta query puede ser lento e innecesario. Siempre aplica filtros de tiempo o contexto para reducir el conjunto de datos, mejorando el rendimiento y la relevancia.
  • Olvidar el parámetro "size": 0: Si no se establece, Elasticsearch devolverá los documentos de búsqueda además de los resultados de agregación, aumentando el tráfico de red y el tiempo de respuesta. Para puros analytics, pon siempre "size": 0.
  • Malinterpretar agregaciones anidadas en jerarquías complejas: En agregaciones multi-nivel (como términos dentro de histogramas), asegúrate de entender que las métricas en niveles internos se calculan dentro del contexto de cada bucket padre, no globalmente.

Checklist de dominio

  1. ¿Puedes diferenciar entre una agregación métrica (ej., avg, sum) y una de buckets (ej., terms, date_histogram) y explicar cuándo usar cada una?
  2. ¿Sabes construir una agregación combinada que agrupe documentos por un campo y calcule al menos dos métricas diferentes dentro de cada grupo?
  3. ¿Eres capaz de aplicar filtros de tiempo (range) en la consulta para limitar las agregaciones a un período relevante, como "últimos 7 días"?
  4. ¿Puedes identificar y corregir el error de usar un campo text en una agregación de términos, cambiándolo a keyword?
  5. ¿Sabes configurar el parámetro size en una agregación de términos para controlar el número de buckets devueltos, evitando sobrecarga?
  6. ¿Entiendes cómo el parámetro "size": 0 en la búsqueda optimiza las consultas puramente analíticas?
  7. ¿Puedes traducir un KPI de negocio (ej., "ventas promedio por región") a una solicitud de agregación en Elasticsearch?

Implementar un dashboard de KPIs para una tienda online

Configura un índice en Elasticsearch y usa agregaciones para calcular KPIs esenciales que luego visualizarás en Kibana. Sigue estos pasos:

  1. Prepara el entorno: Crea un índice llamado kpis_tienda con el siguiente mapeo. Usa la API de Elasticsearch para crearlo:
    PUT /kpis_tienda
    {
      "mappings": {
        "properties": {
          "producto": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
          "categoria": { "type": "keyword" },
          "precio": { "type": "float" },
          "cantidad": { "type": "integer" },
          "fecha": { "type": "date" },
          "cliente_tipo": { "type": "keyword" }
        }
      }
    }
  2. Inserta datos de ejemplo: Indexa al menos 20 documentos simulando ventas. Usa un script o la API bulk. Ejemplo de un documento:
    POST /kpis_tienda/_doc
    {
      "producto": "Laptop Gaming",
      "categoria": "Electrónica",
      "precio": 1200.50,
      "cantidad": 1,
      "fecha": "2024-01-15T10:30:00",
      "cliente_tipo": "Premium"
    }
  3. Diseña las agregaciones: Escribe consultas de agregación para calcular:
    • Total de ingresos (suma de precio * cantidad).
    • Número de ventas por categoría.
    • Precio promedio por tipo de cliente.
    • Ventas diarias en los últimos 30 días (usa un date_histogram).
    Asegúrate de incluir filtros de fecha donde sea relevante.
  4. Verifica en Kibana: Crea un índice pattern en Kibana para kpis_tienda, luego usa Lens o Visualize para construir un dashboard con al menos dos gráficos basados en tus agregaciones (ej., un gráfico de barras de ventas por categoría y una línea de tendencia de ingresos diarios).
  5. Documenta: Guarda las consultas de agregación y captura pantallas del dashboard. Explica cómo cada KPI ayuda en la toma de decisiones.
Pistas
  • Para calcular ingresos totales, necesitarás una agregación de suma sobre un campo script que multiplique precio * cantidad, o indexa un campo calculado previamente.
  • En el date_histogram, usa un intervalo como "1d" y filtra con "range" en la consulta para limitar a los últimos 30 días.
  • Si Kibana no muestra datos, verifica que el índice pattern esté configurado correctamente y que los campos de fecha tengan el formato adecuado.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.