Счетчик документов в сегментах ключевых слов из списка в документе как агрегация в Elasticsearch

Ситуация:

Я новичок в Elasticsearch и не могу понять, как использовать агрегаты, чтобы получить то, что мне нужно.

У меня есть документы со следующей структурой:

{
    ...
    "authors" : [
      {
        "name" : "Bob",
        "@type" : "Person"
      }
    ],
    "resort": "Politics",
    ...
}

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

Что я пробовал:

Поскольку агрегация terms работала с полем resort, я пытался использовать ее с полем authors или name внутри, но всегда не получал сегментов. Для этого я использовал следующий curl запрос:

curl -X POST 'localhost:9200/news/_doc/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "_source": false,
  "aggs": {
    "author_agg": { "terms": {"field": "authors.keyword" } }
  }
}'

Я пришел к выводу, что агрегация terms не работает с полями, содержащимися в списке.

Затем я подумал об агрегации nested, но в документации сказано, что это

агрегация одного сегмента

так что не то, что я ищу. Поскольку у меня закончились идеи, я попробовал, но получил ошибку

"type" : "aggregation_execution_exception",
"reason" : "[nested] nested path [authors] is not nested"

Я нашел этот ответ и попытался использовать его для своих данных. У меня был следующий запрос:

curl -X GET "localhost:9200/news/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "nest": {
      "nested": {
        "path": "authors"
      },
      "aggs": {
        "authorname": {
          "terms" : {
            "field": "name.keyword"
          }
        }
      }
    }
  }
}'

который дал мне ошибку

"type" : "aggregation_execution_exception",
"reason" : "[nested] nested path [authors] is not nested"

Я искал, как сделать мой путь вложенным с помощью сопоставлений, но я не мог найти, как это сделать. Я даже не знаю, имеет ли это на самом деле смысл или нет.

Итак, как я могу объединить документы в сегменты на основе ключа, который находится в элементах списка внутри документов?

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


person chrisl    schedule 16.05.2018    source источник


Ответы (1)


Я наконец решил свою проблему:

Идея получить сопоставление клавиш authors nested была совершенно правильной. Но, к сожалению, Elasticsearch не позволяет вам напрямую изменить тип с un-nested на nested, потому что все элементы в этом ключе также должны быть проиндексированы. Итак, вам нужно пройти следующий путь:

  1. Создайте новый индекс с пользовательским сопоставлением. Здесь мы заходим в тип документа _doc, в его свойства, а затем в поле документов authors. Там мы устанавливаем type на nested.

~

curl -X PUT "localhost:9200/new_index?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "_doc" : {
      "properties" : {
        "authors": { "type": "nested" }
      }
    }
  }
}'
  1. Затем мы переиндексируем наш набор данных и устанавливаем место назначения для нашего вновь созданного индекса. Это проиндексирует данные из старого индекса в новый индекс, по существу скопировав чистые данные, но приняв новое сопоставление (поскольку настройки и сопоставления таким образом не копируются).

~

curl -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "old_index"
  },
  "dest": {
    "index": "new_index"
  }
}'

Теперь мы можем выполнить здесь агрегацию nested, чтобы отсортировать документы по корзинам на основе авторов:

curl -X GET 'localhost:9200/new_index/_doc/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "authors": {
      "nested": {
        "path": "authors"
      },
      "aggs": {
        "authors_by_name": {
          "terms": { "field": "authors.name.keyword" }
        }
      }
    }
  }
}'

Я до сих пор не знаю, как переименовать индексы, но, конечно, вы можете просто удалить старый индекс, а затем выполнить описанную процедуру, чтобы создать другой новый индекс с именем старого, но с пользовательским сопоставлением.

person chrisl    schedule 20.05.2018