Как вычислить и добавить метаданные в существующий индекс Elasticsearch?
Я загрузил более 38 миллионов документов (текстовых строк) в индекс Elasticsearch на моем локальном компьютере. Я хотел бы вычислить длину каждой строки и добавить это значение в качестве метаданных в индекс.
Должен ли я вычислять длину строк как метаданные перед загрузкой документов в Elasticsearch? Или я могу обновить метаданные вычисленным значением после факта?
Я относительно новичок в Elasticsearch / Kibana, и эти вопросы возникли из-за следующих экспериментов Python:
Данные в виде списка строк
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 занимает большой кусок памяти.
Данные в виде индекса 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
Оба варианта будут работать, попробуйте и выберите тот, который лучше всего соответствует вашим потребностям.