Blog

Introducción de la interfaz de reglas de consulta Elasticsearch en Kibana

Aprende a usar la interfaz de Reglas de Consulta de Elasticsearch para agregar o excluir documentos de consultas de búsqueda usando conjuntos de reglas personalizables en Kibana, sin afectar al ranking orgánico.

La función de un motor de búsqueda es devolver resultados relevantes. Sin embargo, hay necesidades empresariales que van más allá de eso, como destacar las ventas, priorizar productos de temporada o mostrar artículos patrocinados, y los desarrolladores no siempre pueden hacer esto en la consulta de búsqueda.

Además, estos casos de uso suelen ser sensibles al tiempo, y pasar por las etapas típicas de desarrollo (crear una rama de código y luego esperar una nueva versión) es un proceso que consume mucho tiempo.

Entonces, ¿y si pudiéramos hacer todo este proceso solo con una llamada a la API, o mejor aún, con solo unos clics en Kibana?

Interfaz de Reglas de Consulta

Elasticsearch 8.10 introdujo Reglas de Consulta y Retriever de Reglas. Estas son herramientas diseñadas para inyectar resultados fijados en las consultas sin afectar la clasificación de los resultados orgánicos según reglas. Solo agregan lógica de negocio encima de los resultados de forma declarativa y sencilla.

Algunos casos de uso comunes para las Reglas de Consulta son:

  • Destacar anuncios u ofertas promocionadas: Mostrar artículos en oferta o patrocinados en la parte superior.

  • Excluyendo por contexto o geolocalización: ocultar ciertos objetos cuando la normativa local no permite mostrarlos.

  • Priorizar los resultados clave: Cerciorar de que las búsquedas populares o fijas estén siempre en la cima, independientemente del ranking orgánico.

Para acceder a la interfaz e interactuar con estas herramientas, necesitas hacer clic en el menú lateral de Kibana e ir a Reglas de consulta, en Relevancia:

Acceso a las reglas de consulta en Elasticsearch bajo relevancia

Cuando aparezca el menú de reglas de consulta, haz clic en Crear tu primer conjunto de reglas:

Crear tu primer conjunto de reglas de consulta en Elasticsearch

A continuación, tienes que nombrar tu conjunto de normas.

Nombrar tu conjunto de reglas de consulta en Elasticsearch

La forma para definir cada regla tiene tres componentes clave:

  • Criterios: Las condiciones que deben cumplir para que la norma se aplique. Por ejemplo, "cuando el campo query_string contiene el valor Christmas" o "cuando el campo del país es CO."

  • Acción: Esto es lo que quieres que ocurra cuando se cumplan las condiciones. Puede fijar (fijar un documento a los resultados superiores) o excluir (ocultar un documento).

  • Metadatos: Estos son los campos que acompañan la consulta cuando se ejecuta. Pueden incluir la información del usuario (como ubicación o idioma), así como datos de búsqueda (query_string). Estos son los valores que emplean los criterios para decidir si aplicar o no una regla.

Ejemplo: objetos populares

Imaginemos que tenemos un sitio de comercio electrónico con diferentes artículos. Al analizar las métricas, observamos que uno de los artículos más vendidos en la categoría de consolas es el "DualShock 4 Wireless Controller", especialmente cuando los usuarios buscan las palabras clave "PS4" o "PlayStation 4". Así que decidimos poner este producto encima de los resultados cada vez que un usuario busque esas palabras clave.

Primero, indexemos los documentos de cada elemento usando una solicitud Bulk API:

POST _bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "id": "1", "name": "PlayStation 4 Slim 1TB", "category": "console", "brand": "Sony", "price": 1200 }
{ "index": { "_index": "products", "_id": "2" } }
{ "id": "2", "name": "DualShock 4 Wireless Controller", "category": "accessory", "brand": "Sony", "price": 250 }
{ "index": { "_index": "products", "_id": "3" } }
{ "id": "3", "name": "PlayStation 4 Camera", "category": "accessory", "brand": "Sony", "price": 200 }
{ "index": { "_index": "products", "_id": "4" } }
{ "id": "4", "name": "PlayStation 4 VR Headset", "category": "accessory", "brand": "Sony", "price": 900 }
{ "index": { "_index": "products", "_id": "5" } }
{ "id": "5", "name": "Charging Station for DualShock 4", "category": "accessory", "brand": "Sony", "price": 80 }

Si no intervenimos en la consulta, el elemento suele aparecer en cuarto lugar. Aquí está la pregunta:

GET products/_search
{
 "query": {
   "match": {
     "name": "PlayStation 4"
   }
 }
}

Y aquí están los resultados

{
 "took": 1,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 0.6973252,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "2",
       "_score": 0.08701137,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

Vamos a crear una regla de consulta para cambiar esto. Primero, vamos a agregarlo al reglamento de esta manera:

Cómo editar un conjunto de reglas de consulta en Elasticsearch

O solicitud API equivalente:

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-1232",
      "type": "pinned",
      "criteria": [
        {
          "type": "exact",
          "metadata": "query_string",
          "values": [
            "PS4",
            "PlayStation 4"
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}

Para usar el conjunto de reglas en nuestra consulta, debemos usar un tipo de regla de consulta. Este tipo de consulta se compone de dos partes principales:

GET /products/_search
{
 "retriever": {
   "rule": {
     "retriever": {
       "standard": {
         "query": {
           "match": { "name": "PlayStation 4" }
         }
       }
     },
     "match_criteria": {
       "query_string": "PlayStation 4"
     },
     "ruleset_ids": ["my-rules"]
   }
 }
}
  • match_criteria: Estos son los metadatos que se emplean para comparar con la consulta del usuario. En este ejemplo, el conjunto de reglas se activa cuando el campo query_string tiene el valor "PlayStation 4."

  • Consulta: La consulta real que se usará para buscar y obtener los resultados orgánicos.

De este modo, primero ejecutas la consulta orgánica y luego Elasticsearch aplica las reglas de tu conjunto de reglas:

{
 "took": 17,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 1.7014122e+38,
   "hits": [
     {
       "_index": "products",
       "_id": "2",
       "_score": 1.7014122e+38,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

Ejemplo: metadatos basados en el usuario

Otra aplicación interesante de las Reglas de Consulta es usar metadatos para mostrar documentos específicos basar en información contextual del usuario o del sitio web.

Por ejemplo, imaginemos que queremos destacar artículos o ventas personalizadas basándonos en el nivel de fidelidad del usuario, representado como un valor numérico.

Podemos hacerlo ingiriendo estos metadatos directamente en la consulta para que las reglas se activen cuando dicho valor cumple ciertos criterios.

Primero, indexaremos un documento que solo los usuarios con un alto nivel de lealtad puedan ver:

POST _bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "id": "6", "name": "PlayStation Plus Deluxe Card - 12 months", "category": "membership", "brand": "Sony", "price": 300 }

Ahora, creemos una nueva regla dentro del mismo conjunto de reglas para que cuando el loyalty_level sea igual o superior a 80, el elemento aparezca encima de los resultados.

Cómo editar un conjunto de reglas de consulta en Elasticsearch

Almacena la regla y el reglamento.

Aquí está la solicitud REST equivalente:

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "pin-premiun-user",
      "type": "pinned",
      "criteria": [
        {
          "type": "gte",
          "metadata": "loyalty_level",
          "values": [
            80
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "6"
          }
        ]
      }
    }
  ]
}

Ahora, al ejecutar una consulta, necesitamos incluir el nuevo parámetro loyalty_level en los metadatos. Si se cumple la condición de la regla, el nuevo documento aparecerá encima de los resultados.

Por ejemplo, al enviar una consulta donde el loyalty_level es 80:

POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 80
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}

Veremos el documento de lealtad encima de los resultados:

{
  "took": 31,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 1.7014122e+38,
    "hits": [
      {
        "_index": "products",
        "_id": "6",
        "_score": 1.7014122e+38,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      }
    ]
  }
}

En el caso siguiente, dado que el nivel de lealtad es 70, la regla no se cumple y el objeto no debería aparecer arriba:

POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 70
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}

Aquí están los resultados:

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.5054567,
    "hits": [
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 0.3817649,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      }
    ]
  }
}

Ejemplo: exclusión inmediata

Supongamos que nuestro mando inalámbrico DualShock 4 (ID 2) está temporalmente indisponible y no puede vender. Así que, en lugar de eliminar manualmente el documento o esperar a que algún proceso de datos se active, el equipo de negocio decide eliminarlo de los resultados de búsqueda mientras tanto.

Usaremos un proceso similar al que acabamos de aplicar a los objetos populares, pero esta vez en lugar de seleccionar Fijado, elegiremos Excluir. Esta regla funciona como una especie de lista negra. Cambia los criterios a Siempre para que la exclusión funcione cada vez que se ejecute la consulta.

La regla debería ser así:

Ejemplo de un conjunto de reglas de exclusión inmediata en Elasticsearch

Almacena la regla y el conjunto de reglas para aplicar los cambios. Aquí está la solicitud REST equivalente:

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-6358",
      "type": "pinned",
      "criteria": [
        {
          "type": "always"
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}

Ahora, cuando ejecutamos la consulta de nuevo, verás que el elemento ya no aparece en los resultados, aunque la regla anterior sea fijarlo. Esto se debe a que las exclusiones tienen prioridad sobre los resultados de fijación.

{
 "took": 6,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 4,
     "relation": "eq"
   },
   "max_score": 2.205655,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 2.205655,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 1.9738505,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 1.9738505,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.69247496,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

Conclusión

Las Reglas de Consulta facilitan mucho ajustar la relevancia sin ningún cambio en el código. La nueva interfaz Kibana te permite realizar estos cambios en cuestión de segundos, dándote a ti y a tu equipo empresarial más control sobre los resultados de búsqueda.

Más allá del comercio electrónico, las Reglas de Consulta pueden impulsar muchos otros escenarios: destacar guías de resolución de problemas en portales de soporte, mostrar documentos internos clave en bases de conocimiento, promover noticias de última hora en sitios de noticias o filtrar ofertas de empleo o contenido caducado. Incluso pueden hacer cumplir normas de cumplimiento, como ocultar material restringido por rol de usuario o región.

Contenido relacionado

Cómo migrar datos entre diferentes versiones de Elasticsearch y entre clusters

Kofi Bartlett

Elasticsearch en JavaScript de la manera correcta, parte II

Jeffrey Rengifo

Implementación de búsqueda semántica: Construcción de una búsqueda de recetas con Elasticsearch

Andre Luiz

Cómo desplegar Elasticsearch en AWS Marketplace

Eduard Martin

Cómo desplegar Elasticsearch en Azure AKS Automatic

Eduard Martin

¿Estás listo para crear experiencias de búsqueda de última generación?

No se logra una búsqueda suficientemente avanzada con los esfuerzos de uno. Elasticsearch está impulsado por científicos de datos, operaciones de ML, ingenieros y muchos más que son tan apasionados por la búsqueda como tú. Conectemos y trabajemos juntos para crear la experiencia mágica de búsqueda que te dará los resultados que deseas.

Pruébalo tú mismo