2016-01-05 6 views
1

Скажите, что каждый документ в моем индексе elasticsearch - это сообщение в блоге, которое состоит всего из двух полей, заголовков и тегов. Заголовок - это просто строка, а теги - поле многозначного значения.Как сделать агрегацию ковша в многозначном поле в elasticsearch

Если у меня есть три документа, как это:

title  tags 
"blog1" [A,B,C] 
"blog2" [A,B] 
"blog3" [B,C] 

Я хотел бы ведро уникальных значений всех возможных тегов, но как я могу получить результаты, как показано ниже, который содержит три элемента в ведре. Или есть эффективные альтернативы?

{A: ["blog1", "blog2"]} 
{B: ["blog1", "blog2", "blog3"]} 
{C: ["blog1", "blog3"]} 

Было бы хорошо, если бы кто-то мог дать ответ в API-интерфейсе elasticsearch python.

ответ

2

Вы можете просто использовать агрегацию terms на поле tags и еще одну вложенную подкатегорию top_hits. По следующему запросу вы получите ожидаемые результаты.

{ 
    "size": 0, 
    "aggs": { 
     "tags": { 
      "terms": { 
       "field": "tags" 
      }, 
      "aggs": { 
       "top_titles": { 
        "top_hits": { 
         "_source": ["title"] 
        } 
       } 
      } 
     } 
    } 
} 

Используя это с Python прост:

from elasticsearch import Elasticsearch 
client = Elasticsearch() 

response = client.search(
    index="my-index", 
    body= { 
    "size": 0, 
    "aggs": { 
     "tags": { 
      "terms": { 
       "field": "tags" 
      }, 
      "aggs": { 
       "top_titles": { 
        "top_hits": { 
         "_source": ["title"] 
        } 
       } 
      } 
     } 
    } 
} 
) 

# parse the tags 
for tag in response['aggregations']['tags']['buckets']: 
    tag = tag['key'] # => A, B, C 
    # parse the titles for the tag 
    for hit in tag['top_titles']['hits']['hits']: 
     title = hit['_source']['title'] # => blog1, blog2, ...