query multi example aggs aggregations elasticsearch aggregate faceted-search

multi - Cómo obtener una agregación Elasticsearch con múltiples campos



multi match elasticsearch (1)

Estoy intentando encontrar etiquetas relacionadas con la que se está viendo actualmente. Todos los documentos en nuestro índice están etiquetados. Cada etiqueta está formada por dos partes: una identificación y un nombre de texto:

{ ... meta: { ... tags: [ { id: 123, name: ''Biscuits'' }, { id: 456, name: ''Cakes'' }, { id: 789, name: ''Breads'' } ] } }

Para buscar las etiquetas relacionadas, simplemente estoy consultando los documentos y obteniendo un agregado de sus etiquetas:

{ "query": { "bool": { "must": [ { "match": { "item.meta.tags.id": "123" } }, { ... } ] } }, "aggs": { "baked_goods": { "terms": { "field": "item.meta.tags.id", "min_doc_count": 2 } } } }

Esto funciona perfectamente, obtengo los resultados que quiero. Sin embargo, necesito tanto la identificación de la etiqueta como su nombre para hacer algo útil. He explorado cómo lograr esto, las soluciones parecen ser:

  1. Combina los campos al indexar
  2. Un script para juntar los campos
  3. Una agregación anidada

La opción uno y dos no están disponibles para mí, así que he estado yendo con 3 pero no estoy respondiendo de la manera esperada. Dada la siguiente consulta (sigue buscando documentos también etiquetados con ''Biscuits''):

{ ... "aggs": { "baked_goods": { "terms": { "field": "item.meta.tags.id", "min_doc_count": 2 }, "aggs": { "name": { "terms": { "field": "item.meta.tags.name" } } } } } }

Conseguiré este resultado:

{ ... "aggregations": { "baked_goods": { "buckets": [ { "key": "456", "doc_count": 11, "name": { "buckets": [ { "key": "Biscuits", "doc_count": 11 }, { "key": "Cakes", "doc_count": 11 } ] } } ] } } }

La agregación anidada incluye tanto el término de búsqueda como la etiqueta que estoy buscando (devuelta en orden alfabético).

Intenté mitigar esto agregando una exclude a la agregación anidada, pero esto ralentizó la consulta demasiado (alrededor de 100 veces para 500000 documentos). Hasta ahora, la solución más rápida es deducir el resultado manualmente.

¿Cuál es la mejor manera de obtener una agregación de etiquetas con la identificación de la etiqueta y el nombre de la etiqueta en la respuesta?

¡Gracias por llegar tan lejos!


Por lo que parece, tus tags no están nested . Para que funcione esta agregación, la necesita nested para que haya una asociación entre una id y un name . Sin nested la lista de id s es solo una matriz y la lista de name es otra matriz:

"item": { "properties": { "meta": { "properties": { "tags": { "type": "nested", <-- nested field "include_in_parent": true, <-- to, also, keep the flat array-like structure "properties": { "id": { "type": "integer" }, "name": { "type": "string" } } } } } } }

Además, tenga en cuenta que he agregado a la asignación esta línea "include_in_parent": true que significa que sus etiquetas nested también se comportarán como una estructura "plana" similar a una matriz.

Por lo tanto, todo lo que tenía hasta ahora en sus consultas seguirá funcionando sin ningún cambio en las consultas.

Pero, para esta consulta particular tuya, la agregación debe cambiar a algo como esto:

{ "aggs": { "baked_goods": { "nested": { "path": "item.meta.tags" }, "aggs": { "name": { "terms": { "field": "item.meta.tags.id" }, "aggs": { "name": { "terms": { "field": "item.meta.tags.name" } } } } } } } }

Y el resultado es así:

"aggregations": { "baked_goods": { "doc_count": 9, "name": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": 123, "doc_count": 3, "name": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "biscuits", "doc_count": 3 } ] } }, { "key": 456, "doc_count": 2, "name": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "cakes", "doc_count": 2 } ] } }, .....