API обновления по запросу
Обновляет документы, соответствующие указанному запросу. Если запрос не указан, выполняется обновление каждого документа в потоке данных или индексе без изменения источника, что полезно для внесения изменений в схему.
POST my-index-000001/_update_by_query?conflicts=proceed
Запрос
POST /<target>/_update_by_query
Предварительные требования
-
Если включены функции безопасности Elasticsearch, у вас должны быть следующие права доступа к индексам для целевого потока данных, индекса или псевдонима:
-
read -
indexилиwrite
-
Описание
Вы можете указать критерии запроса в URI запроса или в теле запроса, используя ту же синтаксическую конструкцию, что и в API поиска.
При отправке запроса обновления по запросу Elasticsearch получает моментальный снимок данных потока или индекса в момент начала обработки запроса и обновляет соответствующие документы с использованием internal версионирования. Когда версии совпадают, документ обновляется, а номер версии увеличивается. Если документ изменяется между моментом получения моментального снимка и обработкой операции обновления, возникает конфликт версий, и операция завершается неудачей. Вы можете выбрать подсчёт конфликтов версий вместо остановки и возврата, задав conflicts на proceed. Обратите внимание, что если вы выберете подсчёт конфликтов версий, операция может попытаться обновить больше документов из источника, чем max_docs, пока не обновит успешно max_docs документов или не пройдёт все документы в исходном запросе.
Документы с версией, равной 0, не могут быть обновлены с помощью обновления по запросу, потому что internal версионирование не поддерживает 0 в качестве допустимого номера версии.
При обработке запроса обновления по запросу Elasticsearch выполняет несколько последовательных запросов поиска для поиска всех соответствующих документов. Для каждой группы соответствующих документов выполняется запрос массового обновления. Любые ошибки запроса или обновления приводят к неудаче запроса обновления по запросу, и ошибки отображаются в ответе. Все запросы обновления, завершившиеся успешно, сохраняются, они не отменяются.
Обновление фрагментов
Указание параметра refresh обновляет все фрагменты после завершения запроса. Это отличается от параметра refresh API обновления, который обновляет только фрагмент, получивший запрос. В отличие от API обновления, он не поддерживает wait_for.
Асинхронное выполнение обновления по запросу
Если запрос содержит wait_for_completion=false, Elasticsearch выполняет некоторые проверки предварительной обработки, запускает запрос и возвращает task, который можно использовать для отмены или получения статуса задачи. Elasticsearch создаёт запись об этой задаче в виде документа по адресу .tasks/task/${taskId}. Когда вы закончите с задачей, вы должны удалить документ задачи, чтобы Elasticsearch мог освободить место.
Ожидание активных фрагментов
wait_for_active_shards управляет тем, сколько копий фрагмента должно быть активным перед продолжением запроса. Подробнее см. Активные фрагменты. timeout управляет тем, как долго каждый запрос записи ждёт, пока недоступные фрагменты не станут доступными. Оба работают точно так же, как и в API массовой обработки. Обновление по запросу использует прокрученные поиски, поэтому вы также можете указать параметр scroll для управления временем сохранения контекста поиска, например ?scroll=10m. По умолчанию значение равно 5 минутам.
Ограничение запросов обновления
Чтобы контролировать скорость, с которой обновление по запросу отправляет пакеты операций обновления, вы можете установить requests_per_second на любое положительное десятичное число. Это добавляет время ожидания к каждому пакету для регулирования скорости. Установите requests_per_second на -1, чтобы отключить ограничение скорости.
Ограничение скорости использует время ожидания между пакетами, чтобы внутренние запросы прокрутки могли получить таймаут, учитывающий задержку запроса. Время задержки — это разница между размером пакета, делённым на requests_per_second, и временем записи. По умолчанию размер пакета равен 1000, поэтому, если requests_per_second установлено на 500:
target_time = 1000 / 500 per second = 2 seconds wait_time = target_time - write_time = 2 seconds - .5 seconds = 1.5 seconds
Поскольку пакет отправляется как один запрос _bulk, большие размеры пакетов приводят к созданию Elasticsearch многих запросов и ожидания перед запуском следующего набора. Это «импульсное», а не «плавное» выполнение.
Разбиение
Обновление по запросу поддерживает скроллинг по кускам для параллелизации процесса обновления. Это может повысить эффективность и предоставить удобный способ разбить запрос на более мелкие части.
Установка slices на auto выбирает разумное число для большинства потоков данных и индексов. Если вы разделяете вручную или иначе настраиваете автоматическое разделение, имейте в виду, что:
- Производительность запроса наиболее эффективна, когда количество
slicesравно количеству фрагментов в индексе или базовом индексе. Если это число велико (например, 500), выберите меньшее число, так как слишком многоslicesнегативно влияет на производительность. Установкаslicesвыше числа фрагментов, как правило, не улучшает эффективность и добавляет издержки. - Производительность обновления масштабируется линейно с доступными ресурсами с увеличением количества кусков.
То, какая производительность, запроса или обновления, доминирует во время выполнения, зависит от переиндексируемых документов и ресурсов кластера.
Параметры пути
-
<target> - (Необязательный, строка) Список потоков данных, индексов и псевдонимов, разделённых запятыми, для поиска. Поддерживает подстановки (
*). Чтобы выполнить поиск по всем потокам данных или индексам, опустите этот параметр или используйте*или_all.
Параметры запроса
-
allow_no_indices -
(Необязательно, булево) Если
false, запрос возвращает ошибку, если какие-либо выражения с подстановкой, псевдоним индекса или_allзначение указывают только на отсутствующие или закрытые индексы. Это поведение применяется даже если запрос направлен на другие открытые индексы. Например, запрос, направленный наfoo*,bar*, возвращает ошибку, если индекс начинается сfoo, но ни один индекс не начинается сbar.По умолчанию
true. -
analyzer -
(Необязательно, строка) Анализатор для использования в строке запроса.
Этот параметр может использоваться только при указании параметра строки запроса
q. -
analyze_wildcard -
(Необязательно, булево) Если
true, запросы с подстановкой и префиксом анализируются. По умолчаниюfalse.Этот параметр может использоваться только при указании параметра строки запроса
q. -
conflicts - (Необязательно, строка) Действие при столкновении с конфликтами версий при обновлении по запросу:
abortилиproceed. По умолчаниюabort. -
default_operator -
(Необязательно, строка) Оператор по умолчанию для запроса строки: AND или OR. По умолчанию
OR.Этот параметр может использоваться только при указании параметра строки запроса
q. -
df -
(Необязательно, строка) Поле, используемое по умолчанию, когда в строке запроса не указан префикс поля.
Этот параметр может использоваться только при указании параметра строки запроса
q. -
expand_wildcards -
(Необязательно, строка) Тип индекса, с которым могут совпадать шаблоны с подстановкой. Если запрос может обращаться к потокам данных, этот аргумент определяет, соответствуют ли выражения с подстановкой скрытым потокам данных. Поддерживает значения, разделенные запятыми, такие как
open,hidden. Допустимые значения:-
all - Совпадение с любым потоком данных или индексом, включая скрытые.
-
open - Совпадение с открытыми, нескрытыми индексами. Также совпадение с любым нескрытым потоком данных.
-
closed - Совпадение с закрытыми, нескрытыми индексами. Также совпадение с любым нескрытым потоком данных. Потоки данных не могут быть закрыты.
-
hidden - Совпадение со скрытыми потоками данных и скрытыми индексами. Должен использоваться вместе с
open,closedили обоими. -
none - Шаблоны с подстановкой не принимаются.
По умолчанию
open. -
-
from - (Необязательно, целое число) Смещение документа для начала. По умолчанию
0. -
ignore_unavailable - (Необязательно, булево) Если
false, запрос возвращает ошибку, если он направлен на отсутствующий или закрытый индекс. По умолчаниюfalse. -
lenient -
(Необязательно, булево) Если
true, сбои запросов, основанные на формате (например, предоставление текста числовому полю) в строке запроса будут проигнорированы. По умолчаниюfalse.Этот параметр может использоваться только при указании параметра строки запроса
q. -
max_docs - (Необязательно, целое число) Максимальное количество документов для обработки. По умолчанию — все документы.
-
pipeline - (Необязательно, строка) Идентификатор конвейера для предварительной обработки входящих документов.
-
preference - (Необязательно, строка) Указывает узел или фрагмент, на котором должна выполняться операция. По умолчанию случайный.
-
q - (Необязательно, строка) Запрос в формате синтаксиса строки запроса Lucene.
-
request_cache - (Необязательно, булево) Если
true, кэширование запросов используется для этого запроса. По умолчанию используется значение на уровне индекса. -
refresh - (Необязательно, булево) Если
true, Elasticsearch обновляет затронутые фрагменты, чтобы сделать операцию видимой для поиска. По умолчаниюfalse. -
requests_per_second - (Необязательно, целое число) Ограничение для этого запроса в подзапросах в секунду. По умолчанию
-1(нет ограничения). -
routing - (Необязательно, строка) Пользовательское значение, используемое для маршрутизации операций на определенный фрагмент.
-
scroll - (Необязательно, значение времени) Период удержания контекста поиска для прокрутки. См. Прокручивание результатов поиска.
-
scroll_size - (Необязательно, целое число) Размер запроса прокрутки, который выполняет операцию. По умолчанию 1000.
-
search_type -
(Необязательно, строка) Тип операции поиска. Доступные варианты:
-
query_then_fetch -
dfs_query_then_fetch
-
-
search_timeout - (Необязательно, единицы времени) Явное ограничение времени для каждого запроса поиска. По умолчанию ограничений нет.
-
slices - (Необязательно, целое число) Количество фрагментов, на которое следует разделить эту задачу. По умолчанию 1, что означает, что задача не разбивается на подзадачи.
-
sort - (Необязательно, строка) Список пар «<поле>:<направление>», разделенных запятыми.
-
stats - (Необязательно, строка) Конкретный
tagзапроса для целей ведения журнала и статистики. -
terminate_after -
(Необязательно, целое число) Максимальное количество документов, собираемых для каждого фрагмента. Если запрос достигает этого предела, Elasticsearch прерывает запрос. Elasticsearch собирает документы до сортировки.
Используйте с осторожностью. Elasticsearch применяет этот параметр к каждому фрагменту, обрабатывающему запрос. Когда это возможно, позвольте Elasticsearch производить автоматическое прерывание запроса. Избегайте указания этого параметра для запросов, которые направлены на потоки данных с поддерживающими индексами по нескольким уровням данных.
-
timeout -
(Необязательно, единицы времени) Период, в течение которого каждый запрос обновления ожидает следующих операций:
- Динамические обновления отображения
- Ожидание активных фрагментов
По умолчанию
1m(одна минута). Это гарантирует, что Elasticsearch подождёт по крайней мере заданное ограничение времени, прежде чем завершится неудачей. Фактическое время ожидания может быть больше, особенно когда происходит несколько ожиданий. -
version - (Необязательно, булево) Если
true, возвращает версию документа как часть совпадения. -
wait_for_active_shards -
(Необязательно, строка) Количество копий фрагментов, которые должны быть активными перед продолжением операции. Установите на
allили любое положительное целое число до общего числа фрагментов в индексе (number_of_replicas+1). По умолчанию: 1, первичный фрагмент.См. Активные фрагменты.
Тело запроса
-
query - (Необязательно, объект запроса) Указывает документы для обновления, используя DSL-запросы.
Тело ответа
-
took - Количество миллисекунд с начала до конца всей операции.
-
timed_out - Этот флаг устанавливается в
true, если какой-либо из запросов, выполненных во время обновления с помощью выполнения запроса, истек по времени. -
total - Количество документов, которые были обработаны успешно.
-
updated - Количество документов, которые были обновлены успешно.
-
deleted - Количество документов, которые были удалены успешно.
-
batches - Количество ответов прокрутки, полученных обновлением по запросу.
-
version_conflicts - Количество конфликтов версий, с которыми столкнулось обновление по запросу.
-
noops - Количество документов, которые были проигнорированы, потому что скрипт, используемый для обновления по запросу, вернул значение
noopдляctx.op. -
retries - Количество попыток повторной обработки, предпринятых обновлением по запросу.
bulk— это количество повторно обработанных массовых действий, аsearch— количество повторно обработанных действий поиска. -
throttled_millis - Количество миллисекунд, в течение которых запрос простаивал, чтобы соответствовать
requests_per_second. -
requests_per_second - Количество запросов в секунду, эффективно выполненных во время обновления по запросу.
-
throttled_until_millis - Это поле всегда должно быть равно нулю в ответе
_update_by_query. Оно имеет смысл только при использовании API задач Задача, где оно указывает следующее время (в миллисекундах с начала эпохи), когда запрос, ограниченный по времени, будет снова выполнен, чтобы соответствоватьrequests_per_second. -
failures - Массив ошибок, если во время процесса возникли какие-либо невосстановимые ошибки. Если он не пустой, запрос был прерван из-за этих ошибок. Обновление по запросу реализовано с использованием пакетов. Любая ошибка приводит к прерыванию всего процесса, но все ошибки в текущем пакете собираются в массив. Вы можете использовать параметр
conflicts, чтобы предотвратить прерывание переиндексации при конфликтах версий.
Примеры
Самое простое использование _update_by_query просто выполняет обновление каждого документа в потоке данных или индексе без изменения источника. Это полезно для добавления нового свойства или каких-либо других онлайн-изменений отображения.
Для обновления выбранных документов укажите запрос в теле запроса:
POST my-index-000001/_update_by_query?conflicts=proceed
{
"query": {
"term": {
"user.id": "kimchy"
}
}
} | Запрос должен быть передан как значение ключу |
Обновление документов в нескольких потоках данных или индексах:
POST my-index-000001,my-index-000002/_update_by_query
Ограничение операции обновления по запросу фрагментами, для которых указано определенное значение маршрутизации:
POST my-index-000001/_update_by_query?routing=1
По умолчанию обновление по запросу использует пакеты прокрутки по 1000. Вы можете изменить размер пакета с помощью параметра scroll_size:
POST my-index-000001/_update_by_query?scroll_size=100
Обновление источника документа
Обновление по запросу поддерживает скрипты для обновления источника документа. Например, следующий запрос увеличивает поле count для всех документов со значением user.id равным kimchy в my-index-000001:
POST my-index-000001/_update_by_query
{
"script": {
"source": "ctx._source.count++",
"lang": "painless"
},
"query": {
"term": {
"user.id": "kimchy"
}
}
} Обратите внимание, что conflicts=proceed не указано в этом примере. В этом случае конфликт версий должен остановить процесс, чтобы вы могли обработать ошибку.
Как и в API обновления, вы можете установить ctx.op, чтобы изменить выполняемую операцию:
| | Установите |
| | Установите |
Обновление по запросу поддерживает только update, noop и delete. Установка ctx.op на другое значение является ошибкой. Установка любого другого поля в ctx является ошибкой. Этот API позволяет только изменять исходные данные совпадающих документов, вы не можете их перемещать.
Обновление документов с помощью конвейера ingest
Обновление по запросу может использовать функцию конвейеров ingest, указав pipeline:
PUT _ingest/pipeline/set-foo
{
"description" : "sets foo",
"processors" : [ {
"set" : {
"field": "foo",
"value": "bar"
}
} ]
}
POST my-index-000001/_update_by_query?pipeline=set-foo Получение статуса операций обновления по запросу
Вы можете получить статус всех выполняемых запросов обновления по запросу с помощью API управления задачами:
GET _tasks?detailed=true&actions=*byquery
Ответы выглядят следующим образом:
{
"nodes" : {
"r1A2WoRbTwKZ516z6NEs5A" : {
"name" : "r1A2WoR",
"transport_address" : "127.0.0.1:9300",
"host" : "127.0.0.1",
"ip" : "127.0.0.1:9300",
"attributes" : {
"testattr" : "test",
"portsfile" : "true"
},
"tasks" : {
"r1A2WoRbTwKZ516z6NEs5A:36619" : {
"node" : "r1A2WoRbTwKZ516z6NEs5A",
"id" : 36619,
"type" : "transport",
"action" : "indices:data/write/update/byquery",
"status" : {
"total" : 6154,
"updated" : 3500,
"created" : 0,
"deleted" : 0,
"batches" : 4,
"version_conflicts" : 0,
"noops" : 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0
},
"description" : ""
}
}
}
}
} | Этот объект содержит фактический статус. Он аналогичен ответу в формате JSON с важным добавлением поля |
С помощью идентификатора задачи вы можете получить доступ к задаче напрямую. Следующий пример извлекает информацию о задаче r1A2WoRbTwKZ516z6NEs5A:36619:
GET /_tasks/r1A2WoRbTwKZ516z6NEs5A:36619
Преимущество этого API заключается в том, что он интегрируется с wait_for_completion=false, чтобы прозрачно возвращать состояние завершенных задач. Если задача завершена и для неё было установлено wait_for_completion=false, она вернётся с полем results или error. Стоимостью этой функции является документ, который wait_for_completion=false создаёт в .tasks/task/${taskId}. Вам необходимо удалить этот документ самостоятельно.
Отмена операции обновления по запросу
Любую операцию обновления по запросу можно отменить, используя API отмены задач:
POST _tasks/r1A2WoRbTwKZ516z6NEs5A:36619/_cancel
Идентификатор задачи можно найти, используя API задач.
Отмена должна происходить быстро, но может занять несколько секунд. API статуса задач выше будет продолжать отображать задачу обновления по запросу до тех пор, пока эта задача не проверит, что она была отменена, и не завершит себя.
Изменение ограничения скорости для запроса
Значение requests_per_second можно изменить на выполняющемся обновлении по запросу, используя API _rethrottle:
POST _update_by_query/r1A2WoRbTwKZ516z6NEs5A:36619/_rethrottle?requests_per_second=-1
Идентификатор задачи можно найти, используя API задач.
Как и при установке значения с помощью API _update_by_query, значение requests_per_second может быть установлено в -1, чтобы отключить ограничение скорости, или в любое десятичное число, например, 1.7 или 12, чтобы установить ограничение на этом уровне. Изменение ограничения скорости, ускоряющее запрос, вступает в силу немедленно, но изменение, замедляющее запрос, вступит в силу после завершения текущей партии. Это предотвращает таймауты при прокрутке.
Ручная нарезка
Разбейте запрос обновления по запросу на части вручную, указав идентификатор части и общее количество частей в каждом запросе:
POST my-index-000001/_update_by_query
{
"slice": {
"id": 0,
"max": 2
},
"script": {
"source": "ctx._source['extra'] = 'test'"
}
}
POST my-index-000001/_update_by_query
{
"slice": {
"id": 1,
"max": 2
},
"script": {
"source": "ctx._source['extra'] = 'test'"
}
} Что можно проверить с помощью:
GET _refresh POST my-index-000001/_search?size=0&q=extra:test&filter_path=hits.total
Что приводит к осмысленному total, например, такому:
{
"hits": {
"total": {
"value": 120,
"relation": "eq"
}
}
} Автоматическая нарезка
Вы также можете позволить обновлению по запросу автоматически распараллеливать использование скроллирования с нарезкой для нарезки по _id. Используйте slices, чтобы указать количество частей:
POST my-index-000001/_update_by_query?refresh&slices=5
{
"script": {
"source": "ctx._source['extra'] = 'test'"
}
} Что также можно проверить с помощью:
POST my-index-000001/_search?size=0&q=extra:test&filter_path=hits.total
Что приводит к осмысленному total, например, такому:
{
"hits": {
"total": {
"value": 120,
"relation": "eq"
}
}
} Установка значения slices в auto позволит Elasticsearch выбрать количество используемых частей. Эта настройка будет использовать по одной части на фрагмент, до определенного предела. Если есть несколько потоков данных или индексов, количество частей будет выбираться на основе индекса или базового индекса с наименьшим количеством фрагментов.
Добавление slices к _update_by_query просто автоматизирует ручной процесс, описанный выше, создавая подзапросы, что означает, что у него есть некоторые особенности:
- Эти запросы можно увидеть в API задач. Эти подзапросы являются "дочерними" задачами для запроса с
slices. - Получение статуса задачи для запроса с
slicesсодержит только статус завершенных частей. - Эти подзапросы индивидуально доступны для таких операций, как отмена и изменение ограничения скорости.
- Изменение ограничения скорости для запроса с
slicesбудет пропорционально изменять ограничение скорости для незавершенных подзапросов. - Отмена запроса с
slicesотменит каждый подзапрос. - Из-за особенностей
slicesкаждый подзапрос не получит идеально равной части документов. Все документы будут обработаны, но некоторые части могут быть больше других. Ожидайте, что у больших частей будет более равномерное распределение. - Параметры, такие как
requests_per_secondиmax_docsв запросе сslices, распределяются пропорционально каждому подзапросу. В сочетании с предыдущим пунктом об неравномерном распределении следует предположить, что использованиеmax_docsсslicesможет не привести к обновлению ровноmax_docsдокументов. - Каждый подзапрос получает немного другую моментальную фотографию потока данных или индекса, хотя все они сделаны примерно в одно и то же время.
Добавление новой свойства
Предположим, вы создали индекс без динамического отображения, заполнили его данными, а затем добавили значение отображения, чтобы получить больше полей из данных:
PUT test
{
"mappings": {
"dynamic": false,
"properties": {
"text": {"type": "text"}
}
}
}
POST test/_doc?refresh
{
"text": "words words",
"flag": "bar"
}
POST test/_doc?refresh
{
"text": "words words",
"flag": "foo"
}
PUT test/_mapping
{
"properties": {
"text": {"type": "text"},
"flag": {"type": "text", "analyzer": "keyword"}
}
} | Это означает, что новые поля не будут индексироваться, а будут храниться в | |
| Это обновляет отображение, добавляя новое поле |
Поиск данных ничего не найдет:
POST test/_search?filter_path=hits.total
{
"query": {
"match": {
"flag": "foo"
}
}
} {
"hits" : {
"total": {
"value": 0,
"relation": "eq"
}
}
} Но вы можете выполнить запрос _update_by_query, чтобы получить новое отображение:
POST test/_update_by_query?refresh&conflicts=proceed
POST test/_search?filter_path=hits.total
{
"query": {
"match": {
"flag": "foo"
}
}
} {
"hits" : {
"total": {
"value": 1,
"relation": "eq"
}
}
} Вы можете сделать то же самое при добавлении поля в многопольное поле.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-update-by-query.html