Как вычислить и добавить метаданные в существующий индекс Elasticsearch?

Я загрузил более 38 миллионов документов (текстовых строк) в индекс Elasticsearch на моем локальном компьютере. Я хотел бы вычислить длину каждой строки и добавить это значение в качестве метаданных в индекс.

Должен ли я вычислять длину строк как метаданные перед загрузкой документов в Elasticsearch? Или я могу обновить метаданные вычисленным значением после факта?

Я относительно новичок в Elasticsearch / Kibana, и эти вопросы возникли из-за следующих экспериментов Python:

  1. Данные в виде списка строк

             mylist = ['string_1', 'string_2',..., 'string_N']
     L = [len(s) for s in mylist]  # this computation takes about 1 minute on my machine
    

    Обратной стороной варианта 1 является то, что я не использую Elasticsearch, а mylist занимает большой кусок памяти.

  2. Данные в виде индекса Elasticsearch, где каждая строка в mylist была загружена в поле text.

             from haystack.document_store.elasticsearch import ElasticsearchDocumentStore
     document_store = ElasticsearchDocumentStore(host='localhost', username='', password='', index='myindex')
     docs = document_store.get_all_documents_generator()
     L = [len(d.text) for d in docs]  # this computation takes about 6 minutes on my machine
    

    Обратной стороной варианта 2 является то, что вычисления занимали гораздо больше времени. Положительный момент - генератор () освободил память. Большое время вычислений - вот почему я подумал, что сохранение длины строки (и другой аналитики) в качестве метаданных в Elasticsearch было бы хорошим решением.

Есть ли другие варианты, которые мне следует рассмотреть? Что мне не хватает?

1 ответ

Если вы хотите сохранить размер всего документа, я предлагаю установитьmapper-sizeплагин , который будет хранить размер исходного документа в _sizeполе.

Если вы хотите сохранить только размер определенного поля исходного документа, вам нужно действовать по-другому.

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

Сначала создайте конвейер загрузки сscriptпроцессор , который будет хранить размер строки в textполе в другом поле, называемом textLength.

      PUT _ingest/pipeline/string-length
{
  "description": "My optional pipeline description",
  "processors": [
    {
      "script": {
        "source": "ctx.textLength = ctx.text.length()"
      }
    }
  ]
}

Итак, если вы уже загрузили документы в Elasticsearch и хотели бы обогатить каждый документ длиной одного из его полей, вы можете сделать это постфактум, используя Update by Query API, например так:

      POST myindex/_update_by_query?pipeline=string-length&wait_for_completion=false

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

      PUT myindex/_doc/123?pipeline=string-length

Оба варианта будут работать, попробуйте и выберите тот, который лучше всего соответствует вашим потребностям.

Другие вопросы по тегам