2015-03-12 3 views
13

Мне нужно удалить поле во всех документах, индексированных в Elasticsearch. Как мне это сделать. Будет ли любой из запросов на удаление помочь мне в этом.Удалить поле из документа Elasticsearch

+0

По умолчанию это невозможно, потому что сейчас Lucene не поддерживает . В основном вы можете только поместить или удалить целые документы Lucene от Показатели Lucene.1 Получите первую версию своего документа 2 удалите поле 3 нажмите эту новую версию своего документа. – Backtrack

ответ

18

Что @backtrack сказал верно, но есть очень удобный способ сделать это в Elasticsearch. Elasticsearch абстрагирует внутреннюю сложность удаления. Вы должны использовать обновление API для достижения этой цели -

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ 
    "script" : "ctx._source.remove(\"name_of_field\")" 
}' 

Вы можете найти более подробную документацию here.

Примечание: В качестве упругого поиска 6 вы должны включать в себя содержание заголовок типа:

-H 'Content-Type: application/json' 
+0

Какова эффективность этого, если у вас есть миллиард документов с этим полем? –

+0

Фактический документ будет удален, а новый будет добавлен для каждого из таких изменений. –

+0

Уведомление для ElasticSearch 5.0: вы должны использовать именованный параметр вместо жестко заданного имени. Параметры быстрее, и они не будут нарушать лимит компиляции скрипта. См. [Документация] (https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html#prefer-params). –

7

По умолчанию это невозможно, потому что сейчас Lucene этого не поддерживает. В основном вы можете только поместить или удалить целые документы Lucene из индексов Lucene.

  1. Получить первую версию дока
  2. удалить поле
  3. толчка новой версии вашего документа
11

Elasticsearch добавляемые update_by_query в 2.3. Этот экспериментальный интерфейс позволяет вам выполнить обновление по всем документам, соответствующим запросу.

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

Вчера я удалил большое поле из своего кластера ES. Я видел устойчивую пропускную способность 10 000 записей в секунду во время update_by_query, ограниченную процессором, а не IO.

Посмотрите на установку conflict=proceed, если в кластере есть другой трафик обновления, или вся работа прекратится, когда он достигнет ConflictError, когда одна из записей обновляется под одной из партий.

Аналогично, установка wait_for_completion=false приведет к тому, что update_by_query будет запущен через интерфейс tasks. В противном случае задание прекратится, если соединение будет закрыто.

URL:

http://localhost:9200/type/_update_by_query?wait_for_completion=false&conflict=proceed 

POST тело:

{ 
    "script": ctx._source.remove("name_of_field"), 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "exists": { 
      "field": "name_of_field" 
      } 
     } 
     ] 
    } 
    } 
} 

По Elasticsearch 1.43, рядный groovy scripting is disabled by default. Вам нужно включить его для встроенного скрипта, подобного этому, путем добавления script.inline: true в ваш файл конфигурации.

Или загрузите groovy в качестве скрипта и используйте формат "script": { "file": "scriptname", "lang": "groovy"}.

+0

Я еще не знаю, как вернуть поле field_data, используемое этим полем. Надеясь, что перезапуск перезагрузки приведет к перезагрузке ординалов. – spazm

+1

Телу нужна была небольшая модификация, но в остальном это прекрасно работает. Мне пришлось обернуть скрипт в объект JSON, возможно, потому, что API немного изменился. – Peter

Смежные вопросы