Aplicar compound queries con bool y boosting

Lectura
20 min~5 min lectura

Concepto clave

Las compound queries en Elasticsearch son consultas que combinan múltiples cláusulas de búsqueda para crear lógica compleja. Dos de las más poderosas son bool y boosting. Imagina que estás buscando candidatos para un puesto de trabajo: con bool puedes decir "quiero alguien con experiencia en Python (debe tener) Y conocimientos en machine learning (debería tener) O al menos 5 años en desarrollo (puede tener)". Con boosting, puedes priorizar ciertos criterios: "prefiero candidatos con experiencia en startups, pero si tienen certificaciones, eso vale más".

La consulta bool usa cuatro tipos de cláusulas: must (debe cumplirse, como un AND), should (debería cumplirse, contribuye al score), must_not (no debe cumplirse, como un NOT), y filter (debe cumplirse, sin afectar el score). Boosting, por otro lado, permite dar más peso a ciertos criterios: puedes "impulsar" documentos que cumplan una condición específica, haciendo que aparezcan más arriba en los resultados, sin excluir los demás.

Cómo funciona en la práctica

Vamos a construir una consulta paso a paso para buscar productos en un e-commerce. Supongamos que tenemos un índice products con campos como name, category, price, y rating. Queremos productos que: 1) Deben estar en la categoría "electronics" (filter), 2) Deben tener "wireless" en el nombre (must), 3) Preferiblemente tengan rating mayor a 4 (should), y 4) No deben tener precio mayor a 1000 (must_not).

{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "wireless" } }
      ],
      "should": [
        { "range": { "rating": { "gt": 4 } } }
      ],
      "must_not": [
        { "range": { "price": { "gt": 1000 } } }
      ],
      "filter": [
        { "term": { "category": "electronics" } }
      ]
    }
  }
}

Para usar boosting, supongamos que queremos impulsar productos con "bluetooth" en el nombre. Podemos modificar la consulta para darles un boost de 2.0:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "wireless" } },
        { "boosting": {
            "positive": { "match": { "name": "bluetooth" } },
            "negative": { "match_all": {} },
            "negative_boost": 0.5
          }
        }
      ],
      "filter": [
        { "term": { "category": "electronics" } }
      ]
    }
  }
}

Caso de estudio

En una plataforma de noticias, necesitamos buscar artículos sobre "cambio climático" que: 1) Deben ser publicados en los últimos 30 días (filter), 2) Deben contener las palabras "calentamiento global" en el título o contenido (must), 3) Preferiblemente sean de fuentes verificadas (should), y 4) No deben ser de opinión (must_not). Además, queremos impulsar artículos con imágenes (boosting).

CampoTipoDescripción
titletextTítulo del artículo
contenttextContenido completo
sourcekeywordFuente (ej., "BBC", "CNN")
datedateFecha de publicación
has_imagesbooleanTrue si tiene imágenes
typekeywordTipo (ej., "news", "opinion")

Consulta implementada:

{
  "query": {
    "bool": {
      "must": [
        { "multi_match": {
            "query": "calentamiento global",
            "fields": ["title", "content"]
          }
        }
      ],
      "should": [
        { "terms": { "source": ["BBC", "CNN", "Reuters"] } },
        { "boosting": {
            "positive": { "term": { "has_images": true } },
            "negative": { "match_all": {} },
            "negative_boost": 0.8
          }
        }
      ],
      "must_not": [
        { "term": { "type": "opinion" } }
      ],
      "filter": [
        { "range": { "date": { "gte": "now-30d/d" } } }
      ]
    }
  }
}
En producción, esta consulta puede manejar miles de artículos diarios, mejorando la relevancia en un 40% según métricas de engagement.

Errores comunes

  • Usar must para todo: Esto actúa como un AND estricto; si un documento no cumple una condición en must, se excluye. En su lugar, usa should para criterios opcionales que mejoren el score.
  • Ignorar filter para condiciones de filtrado: Si usas must para condiciones que no deben afectar el score (como rangos de fecha), desperdicias recursos de cálculo. Filter es más eficiente porque cachea resultados.
  • Configurar mal el boosting: Un boost muy alto (ej., 10.0) puede dominar los resultados, haciendo irrelevantes otros criterios. Prueba con valores como 1.5 a 3.0 y ajusta basado en pruebas A/B.
  • No probar con datos reales: Las consultas pueden comportarse diferente con volúmenes altos; siempre valida con un subset de producción o datos simulados.
  • Olvidar el negative_boost en boosting: Si no se configura, los documentos que no cumplen la condición positiva no se penalizan; usa negative_boost (ej., 0.5) para reducir su score sin excluirlos.

Checklist de dominio

  1. ¿Puedes construir una consulta bool con al menos tres cláusulas diferentes (must, should, filter)?
  2. ¿Sabes cuándo usar filter en vez de must para mejorar el rendimiento?
  3. ¿Puedes aplicar boosting para priorizar documentos con un atributo específico?
  4. ¿Entiendes cómo afecta el score cada cláusula en una consulta bool?
  5. ¿Has probado tus consultas con datos reales o simulados para validar relevancia?
  6. ¿Puedes identificar y corregir errores comunes como boosts excesivos?
  7. ¿Sabes integrar compound queries en un pipeline de búsqueda con Kibana visualizations?

Implementar una búsqueda avanzada para una tienda en línea

En este ejercicio, crearás una consulta compound para un índice de productos en Elasticsearch. Sigue estos pasos:

  1. Prepara un índice llamado shop_products con al menos estos campos: name (text), category (keyword), price (float), stock (integer), y tags (keyword). Inserta 10-15 documentos de ejemplo usando la API de Elasticsearch.
  2. Diseña una consulta bool que busque productos que: deben estar en la categoría "clothing" (filter), deben contener "jacket" en el nombre (must), deberían tener stock mayor a 10 (should), y no deben tener precio mayor a 200 (must_not).
  3. Modifica la consulta para agregar un boosting que impulse productos con la etiqueta "waterproof" en un factor de 2.5.
  4. Ejecuta la consulta usando la API de búsqueda de Elasticsearch y verifica los resultados. Asegúrate de que los documentos con "waterproof" aparezcan más arriba.
  5. Opcional: Crea una visualización en Kibana para mostrar los resultados en un dashboard, usando un data table o bar chart.
Pistas
  • Usa el Kibana Dev Tools para probar tus consultas rápidamente.
  • Recuerda que filter no afecta el score, así que úsalo para condiciones categóricas como la categoría.
  • En boosting, el negative_boost por defecto es 1.0; ajústalo si quieres penalizar documentos sin la etiqueta.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.