API переиндексации
Копирует документы из исходного в целевой индекс.
Исходный индекс может быть любым существующим индексом, алиасом или потоком данных. Целевой индекс должен отличаться от исходного. Например, вы не можете переиндексировать поток данных в себя.
Для переиндексации необходимо, чтобы _source был включен для всех документов в источнике.
Целевой индекс должен быть настроен по вашему желанию перед вызовом _reindex. Переиндексация не копирует настройки из источника или связанной шаблона.
Карты, количество фрагментов, реплики и т. д. должны быть настроены заранее.
resp = client.reindex(
source={
"index": "my-index-000001"
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'my-index-000001'
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001"
}
} Запрос
POST /_reindex
Предварительные условия
-
Если в Elasticsearch включены функции безопасности, у вас должны быть следующие права безопасности:
- Права
readиндекса для исходного потока данных, индекса или алиаса. - Права
writeиндекса для целевого потока данных, индекса или алиаса индекса. - Для автоматического создания потока данных или индекса с запросом API переиндексации, необходимо иметь права
auto_configure,create_indexилиmanageиндекса для целевого потока данных, индекса или алиаса. - При переиндексации с удаленного кластера, у
source.remote.userдолжны быть праваmonitorкластера и праваreadиндекса для исходного потока данных, индекса или алиаса.
- Права
- При переиндексации с удаленного кластера, вы должны явно разрешить удаленный хост в настройке
reindex.remote.whitelistelasticsearch.yml. См. Переиндексация с удаленного. - Автоматическое создание потока данных требует соответствующего шаблона индекса с включенным потоком данных. См. Настройка потока данных.
Описание
Извлекает источник документа из исходного индекса и индексирует документы в целевой индекс. Вы можете скопировать все документы в целевой индекс или переиндексировать подмножество документов.
Подобно _update_by_query, _reindex получает моментальную фотографию источника, но его цель должна быть различной, чтобы избежать конфликтов версий. Элемент dest можно настроить, как и API индекса, для управления оптимистическим контролем одновременности. Пропуск version_type или установка его значения в internal заставляет Elasticsearch бездумно выгружать документы в целевой индекс, перезаписывая любые документы с одинаковым идентификатором.
Установка version_type на external заставляет Elasticsearch сохранять version из источника, создавать отсутствующие документы и обновлять документы, у которых в целевом индексе более старая версия, чем в исходном.
Установка op_type на create заставляет _reindex создавать только отсутствующие документы в целевом индексе. Все существующие документы приведут к конфликту версий.
Так как потоки данных являются дополняемыми, любой запрос переиндексации в целевой поток данных должен иметь op_type create. Переиндексация может только добавлять новые документы в целевой поток данных. Она не может обновлять существующие документы в целевом потоке данных.
По умолчанию конфликты версий прерывают процесс _reindex. Чтобы продолжить переиндексацию при возникновении конфликтов, установите параметр тела запроса "conflicts" в proceed. В этом случае ответ включает количество столкнувшихся конфликтов версий. Обратите внимание, что обработка других типов ошибок не зависит от параметра "conflicts". Кроме того, если вы выбираете подсчет конфликтов версий, операция может попытаться переиндексировать больше документов из источника, чем max_docs, пока она успешно не индексирует max_docs документов в целевой индекс или не пройдет по всем документам в запросе источника.
Асинхронное выполнение переиндексации
Если запрос содержит wait_for_completion=false, Elasticsearch выполняет некоторые предварительные проверки, запускает запрос и возвращает task, который вы можете использовать для отмены или получения статуса задачи. Elasticsearch создает запись об этой задаче как документ в _tasks/<task_id>.
Переиндексация из нескольких источников
Если у вас много источников для переиндексации, лучше переиндексировать их по одному, а не использовать шаблон подстановки для выбора нескольких источников. Таким образом, вы можете возобновить процесс в случае ошибок, удалив частично завершенный источник и начав заново. Это также упрощает распараллеливание процесса: разделите список источников для переиндексации и запустите каждый список параллельно.
Один из способов реализации - bash скрипты:
for index in i1 i2 i3 i4 i5; do
curl -HContent-Type:application/json -XPOST localhost:9200/_reindex?pretty -d'{
"source": {
"index": "'$index'"
},
"dest": {
"index": "'$index'-reindexed"
}
}'
done Ограничение скорости
Установите requests_per_second на любое положительное десятичное число (1.4, 6, 1000 и т. д.) для ограничения скорости, с которой _reindex выпускает партии операций индексации. Запросы ограничены задержкой между партиями. Для отключения ограничения установите requests_per_second в -1.
Ограничение происходит путем ожидания между партиями, чтобы внутреннему тайм-ауту, используемому _reindex, можно было указать время ожидания, учитывающее задержку. Время задержки — это разность между размером партии, деленной на 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 создавать много запросов и затем некоторое время ждать перед запуском следующей группы. Это «импульсное», а не «плавное» поведение.
Изменение ограничения скорости
Значение requests_per_second можно изменить во время работы переиндексации с помощью API _rethrottle:
$params = [
'task_id' => 'r1A2WoRbTwKZ516z6NEs5A:36619',
];
$response = $client->reindexRethrottle($params); resp = client.reindex_rethrottle(
task_id="r1A2WoRbTwKZ516z6NEs5A:36619",
requests_per_second="-1",
)
print(resp) response = client.reindex_rethrottle( task_id: 'r1A2WoRbTwKZ516z6NEs5A:36619', requests_per_second: -1 ) puts response
res, err := es.ReindexRethrottle( "r1A2WoRbTwKZ516z6NEs5A:36619", esapi.IntPtr(-1), ) fmt.Println(res, err)
const response = await client.reindexRethrottle({
task_id: "r1A2WoRbTwKZ516z6NEs5A:36619",
requests_per_second: "-1",
});
console.log(response); POST _reindex/r1A2WoRbTwKZ516z6NEs5A:36619/_rethrottle?requests_per_second=-1
Идентификатор задачи можно найти с помощью API задач.
Так же, как и при установке его в API переиндексации, requests_per_second может быть либо -1 для отключения ограничения скорости, либо любым десятичным числом, например 1.7 или 12, для ограничения до этого уровня. Ускорение переиндексации вступает в силу немедленно, но замедление переиндексации вступит в силу после завершения текущей партии. Это предотвращает таймауты скролла.
Фрагментация
Реиндексация поддерживает скроллинг фрагментами для распараллеливания процесса реиндексации. Эта распараллеливание может повысить эффективность и предоставить удобный способ разбить запрос на более мелкие части.
Реиндексация из удалённых кластеров не поддерживает ручную или автоматическую фрагментацию.
Ручная фрагментация
Вручную разбейте запрос реиндексации, указав идентификатор фрагмента и общее количество фрагментов в каждом запросе:
resp = client.reindex(
source={
"index": "my-index-000001",
"slice": {
"id": 0,
"max": 2
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp)
resp1 = client.reindex(
source={
"index": "my-index-000001",
"slice": {
"id": 1,
"max": 2
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp1) response = client.reindex(
body: {
source: {
index: 'my-index-000001',
slice: {
id: 0,
max: 2
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response
response = client.reindex(
body: {
source: {
index: 'my-index-000001',
slice: {
id: 1,
max: 2
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
slice: {
id: 0,
max: 2,
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response);
const response1 = await client.reindex({
source: {
index: "my-index-000001",
slice: {
id: 1,
max: 2,
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response1); POST _reindex
{
"source": {
"index": "my-index-000001",
"slice": {
"id": 0,
"max": 2
}
},
"dest": {
"index": "my-new-index-000001"
}
}
POST _reindex
{
"source": {
"index": "my-index-000001",
"slice": {
"id": 1,
"max": 2
}
},
"dest": {
"index": "my-new-index-000001"
}
} Вы можете проверить, что это работает, выполнив:
resp = client.indices.refresh()
print(resp)
resp1 = client.search(
index="my-new-index-000001",
size="0",
filter_path="hits.total",
)
print(resp1) response = client.indices.refresh puts response response = client.search( index: 'my-new-index-000001', size: 0, filter_path: 'hits.total' ) puts response
const response = await client.indices.refresh();
console.log(response);
const response1 = await client.search({
index: "my-new-index-000001",
size: 0,
filter_path: "hits.total",
});
console.log(response1); GET _refresh POST my-new-index-000001/_search?size=0&filter_path=hits.total
что приводит к разумному total, подобному этому:
{
"hits": {
"total" : {
"value": 120,
"relation": "eq"
}
}
} Автоматическая фрагментация
Вы также можете позволить _reindex автоматически распараллелить процесс, используя скроллинг фрагментами для фрагментации по _id. Используйте slices для указания количества фрагментов:
resp = client.reindex(
slices="5",
refresh=True,
source={
"index": "my-index-000001"
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
slices: 5,
refresh: true,
body: {
source: {
index: 'my-index-000001'
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
slices: 5,
refresh: "true",
source: {
index: "my-index-000001",
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex?slices=5&refresh
{
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001"
}
} Вы также можете проверить это, выполнив:
resp = client.search(
index="my-new-index-000001",
size="0",
filter_path="hits.total",
)
print(resp) response = client.search( index: 'my-new-index-000001', size: 0, filter_path: 'hits.total' ) puts response
const response = await client.search({
index: "my-new-index-000001",
size: 0,
filter_path: "hits.total",
});
console.log(response); POST my-new-index-000001/_search?size=0&filter_path=hits.total
что приводит к разумному total, подобному этому:
{
"hits": {
"total" : {
"value": 120,
"relation": "eq"
}
}
} Установка slices на auto позволит Elasticsearch выбрать количество фрагментов для использования. Это значение будет использовать один фрагмент на индексный фрагмент, вплоть до определённого лимита. При наличии нескольких источников, оно будет выбирать количество фрагментов на основе индекса или индекса-источника с наименьшим количеством фрагментов.
Добавление slices к _reindex просто автоматизирует ручной процесс, использованный в предыдущем разделе, создавая подзапросы, что означает наличие некоторых особенностей:
- Эти запросы можно увидеть в API задач. Эти подзапросы являются дочерними задачами для запроса с
slices. - Получение статуса задачи для запроса с
slicesсодержит только статус завершённых фрагментов. - Эти подзапросы индивидуально доступны для отмены и повторной ограниченной отправки.
- Повторная ограниченная отправка запроса с
slicesбудет пропорционально повторно ограничивать незавершенные подзапросы. - Отмена запроса с
slicesотменяет каждый подзапрос. - Из-за природы
slicesкаждый подзапрос не получит идеально равной части документов. Все документы будут обработаны, но некоторые фрагменты могут быть больше других. Ожидайте, что большие фрагменты будут иметь более равномерное распределение. - Параметры, такие как
requests_per_secondиmax_docsв запросе сslices, распределяются пропорционально каждому подзапросу. В сочетании с вышеупомянутым неравномерным распределением следует заключить, что использованиеmax_docsсslicesможет не привести к точномуmax_docsпереиндексированных документов. - Каждый подзапрос получает немного отличающуюся моментальную фотографию исходных данных, хотя все они сделаны примерно в одно и то же время.
Выбор количества фрагментов
Если фрагментация автоматическая, установка slices на auto выберет разумное число для большинства индексов. Если фрагментация ручная или требуется настройка автоматической фрагментации, воспользуйтесь следующими рекомендациями.
Производительность запросов наиболее эффективна, когда количество slices равно количеству фрагментов в индексе. Если это число велико (например, 500), выберите меньшее значение, так как слишком большое количество slices ухудшит производительность. Увеличение slices сверх количества фрагментов обычно не улучшает эффективность и добавляет накладные расходы.
Производительность индексирования масштабируется линейно по доступным ресурсам с количеством фрагментов.
От того, запрос или индексирование доминирует по времени выполнения, зависит от переиндексируемых документов и ресурсов кластера.
Маршрутизация реиндексации
По умолчанию, если _reindex видит документ с маршрутизацией, маршрутизация сохраняется, если она не изменяется скриптом. Вы можете установить routing в запросе dest для изменения этого:
-
keep - Устанавливает маршрутизацию в запросе bulk для каждого совпадения на маршрутизацию совпадения. Это значение по умолчанию.
-
discard - Устанавливает маршрутизацию в запросе bulk для каждого совпадения на
null. -
=<some text> - Устанавливает маршрутизацию в запросе bulk для каждого совпадения на весь текст после
=.
Например, вы можете использовать следующий запрос для копирования всех документов из source с именем компании cat в dest с маршрутизацией, установленной на cat.
$params = [
'body' => [
'source' => [
'index' => 'source',
'query' => [
'match' => [
'company' => 'cat',
],
],
],
'dest' => [
'index' => 'dest',
'routing' => '=cat',
],
],
];
$response = $client->reindex($params); resp = client.reindex(
source={
"index": "source",
"query": {
"match": {
"company": "cat"
}
}
},
dest={
"index": "dest",
"routing": "=cat"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'source',
query: {
match: {
company: 'cat'
}
}
},
dest: {
index: 'dest',
routing: '=cat'
}
}
)
puts response res, err := es.Reindex(
strings.NewReader(`{
"source": {
"index": "source",
"query": {
"match": {
"company": "cat"
}
}
},
"dest": {
"index": "dest",
"routing": "=cat"
}
}`))
fmt.Println(res, err) const response = await client.reindex({
source: {
index: "source",
query: {
match: {
company: "cat",
},
},
},
dest: {
index: "dest",
routing: "=cat",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "source",
"query": {
"match": {
"company": "cat"
}
}
},
"dest": {
"index": "dest",
"routing": "=cat"
}
} По умолчанию _reindex использует скроллинг партиями по 1000. Вы можете изменить размер партии с полем size в элементе source:
$params = [
'body' => [
'source' => [
'index' => 'source',
'size' => 100,
],
'dest' => [
'index' => 'dest',
'routing' => '=cat',
],
],
];
$response = $client->reindex($params); resp = client.reindex(
source={
"index": "source",
"size": 100
},
dest={
"index": "dest",
"routing": "=cat"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'source',
size: 100
},
dest: {
index: 'dest',
routing: '=cat'
}
}
)
puts response res, err := es.Reindex(
strings.NewReader(`{
"source": {
"index": "source",
"size": 100
},
"dest": {
"index": "dest",
"routing": "=cat"
}
}`))
fmt.Println(res, err) const response = await client.reindex({
source: {
index: "source",
size: 100,
},
dest: {
index: "dest",
routing: "=cat",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "source",
"size": 100
},
"dest": {
"index": "dest",
"routing": "=cat"
}
} Реиндексация с конвейером обработки данных
Реиндексация также может использовать функцию конвейеров обработки данных, указав pipeline следующим образом:
$params = [
'body' => [
'source' => [
'index' => 'source',
],
'dest' => [
'index' => 'dest',
'pipeline' => 'some_ingest_pipeline',
],
],
];
$response = $client->reindex($params); resp = client.reindex(
source={
"index": "source"
},
dest={
"index": "dest",
"pipeline": "some_ingest_pipeline"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'source'
},
dest: {
index: 'dest',
pipeline: 'some_ingest_pipeline'
}
}
)
puts response res, err := es.Reindex(
strings.NewReader(`{
"source": {
"index": "source"
},
"dest": {
"index": "dest",
"pipeline": "some_ingest_pipeline"
}
}`))
fmt.Println(res, err) const response = await client.reindex({
source: {
index: "source",
},
dest: {
index: "dest",
pipeline: "some_ingest_pipeline",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "source"
},
"dest": {
"index": "dest",
"pipeline": "some_ingest_pipeline"
}
} Параметры запроса
-
refresh - (Необязательно, логическое значение) Если
true, запрос обновляет затронутые шарды, чтобы сделать эту операцию видимой для поиска. По умолчанию —false. -
timeout -
(Необязательно, единицы времени) Период, в течение которого индексирование ожидает следующих операций:
По умолчанию —
1m(одна минута). Это гарантирует, что Elasticsearch будет ждать как минимум время ожидания, прежде чем завершиться с ошибкой. Фактическое время ожидания может быть больше, особенно когда происходит несколько ожиданий. -
wait_for_active_shards -
(Необязательно, строка) Количество копий каждого шарда, которые должны быть активны перед продолжением операции. Установите значение
allили любое неотрицательное целое число до общего числа копий каждого шарда в индексе (number_of_replicas+1). По умолчанию —1, то есть ожидать только активации каждого основного шарда.См. Активные шарды.
-
wait_for_completion - (Необязательно, логическое значение) Если
true, запрос блокируется до завершения операции. По умолчанию —true. -
requests_per_second - (Необязательно, целое число) Регулирование для этого запроса в подзапросах в секунду. По умолчанию —
-1(без регулирования). -
require_alias - (Необязательно, логическое значение) Если
true, назначение должно быть псевдонимом индекса. По умолчанию —false. -
scroll - (Необязательно, единицы времени) Указывает, как долго следует поддерживать согласованное представление индекса для прокручиваемого поиска.
-
slices - (Необязательно, целое число) Количество фрагментов, на которые должна быть разделена эта задача. По умолчанию — 1, то есть задача не разделяется на подзадачи.
-
max_docs - (Необязательно, целое число) Максимальное количество документов для обработки. По умолчанию — все документы. Если установлено значение, меньшее или равное
scroll_size, то для получения результатов операции не будет использоваться прокрутка.
Тело запроса
-
conflicts - (Необязательно, перечисление) Установите значение
proceed, чтобы продолжить переиндексацию, даже если есть конфликты. По умолчанию —abort. -
max_docs - (Необязательно, целое число) Максимальное количество документов для переиндексации. Если конфликты равны
proceed, переиндексация может попытаться переиндексировать больше документов из источника, чемmax_docs, пока не будет успешно проиндексированоmax_docsдокументов в целевой объект, или пока не будут обработаны все документы в исходном запросе. -
source -
-
index - (Обязательно, строка) Имя потока данных, индекса или псевдонима, из которого вы копируете. Также принимает разделенный запятыми список для переиндексации из нескольких источников.
-
query - (Необязательно, объект запроса) Указывает документы для переиндексации с использованием Query DSL.
-
remote -
-
host - (Необязательно, строка) URL-адрес удаленного экземпляра Elasticsearch, из которого вы хотите выполнить индексацию. Обязательно при индексировании из удаленного источника.
-
username - (Необязательно, строка) Имя пользователя для аутентификации с удаленным хостом.
-
password - (Необязательно, строка) Пароль для аутентификации с удаленным хостом.
-
socket_timeout - (Необязательно, единицы времени) Время ожидания чтения удаленного сокета. По умолчанию — 30 секунд.
-
connect_timeout - (Необязательно, единицы времени) Время ожидания подключения к удаленному серверу. По умолчанию — 30 секунд.
-
headers - (Необязательно, объект) Объект, содержащий заголовки запроса.
-
-
size - {Необязательно, целое число) Количество документов для индексации в каждом пакете. Используйте при индексировании из удаленного источника, чтобы гарантировать, что пакеты помещаются в буфер в оперативной памяти, который по умолчанию имеет максимальный размер 100 МБ.
-
slice -
-
id - (Необязательно, целое число) Идентификатор фрагмента для ручного разделения на фрагменты.
-
max - (Необязательно, целое число) Общее количество фрагментов.
-
-
sort -
(Необязательно, список) Разделенный запятыми список пар
<field>:<direction>для сортировки перед индексированием. Используйте в сочетании сmax_docsдля управления тем, какие документы переиндексируются.Устарело в 7.6.
Сортировка при переиндексации устарела. Сортировка при переиндексации никогда не гарантировала индексацию документов в порядке и препятствует дальнейшему развитию переиндексации, например, повышению отказоустойчивости и производительности. При использовании в сочетании с
max_docs, рассмотрите возможность использования фильтра запроса вместо этого. -
_source - (Необязательно, строка) Если
trueпереиндексирует все поля источника. Установите список для переиндексации выбранных полей. По умолчанию —true.
-
-
dest -
-
index - (Обязательно, строка) Имя потока данных, индекса или псевдонима индекса, в который вы копируете.
-
version_type - (Необязательно, перечисление) Версионирование для использования в операции индексирования. Допустимые значения:
internal,external,external_gt,external_gte. Дополнительные сведения см. в разделе Типы версий. -
op_type -
(Необязательно, перечисление) Установите значение create, чтобы индексировать только документы, которые еще не существуют (put if absent). Допустимые значения:
index,create. По умолчанию —index.Для переиндексации в целевой поток данных этот аргумент должен быть
create. -
pipeline - (Необязательно, строка) Имя конвейера для использования.
-
-
script -
-
source - (Необязательно, строка) Скрипт для запуска обновления источника документа или метаданных при переиндексации.
-
lang - (Необязательно, перечисление) Язык скрипта:
painless,expression,mustache,java. Дополнительные сведения см. в разделе Скриптинг.
-
Тело ответа
-
took - (целое число) Общее количество миллисекунд, затраченное на всю операцию.
-
timed_out - ({Булево) Этот флаг установлен в
true, если какой-либо из запросов, выполненных во время переиндексации, истек по времени. -
total - (целое число) Количество успешно обработанных документов.
-
updated - (целое число) Количество документов, которые были успешно обновлены, т.е. документ с тем же ID уже существовал до обновления при переиндексации.
-
created - (целое число) Количество успешно созданных документов.
-
deleted - (целое число) Количество успешно удалённых документов.
-
batches - (целое число) Количество ответов на запросы прокрутки, полученных при переиндексации.
-
noops - (целое число) Количество документов, которые были проигнорированы, потому что скрипт, используемый для переиндексации, вернул значение
noopдляctx.op. -
version_conflicts - (целое число) Количество конфликтов версий, с которыми столкнулась переиндексация.
-
retries - (целое число) Количество попыток повторной обработки, предпринятых переиндексацией.
bulk— количество повторно обработанных операций в массе, аsearch— количество повторно обработанных поисковых операций. -
throttled_millis - (целое число) Количество миллисекунд, на которое запрос был приостановлен для соответствия
requests_per_second. -
requests_per_second - (целое число) Количество запросов в секунду, фактически выполненных во время переиндексации.
-
throttled_until_millis - (целое число) Это поле всегда должно быть равно нулю в ответе
_reindex. Оно имеет значение только при использовании API задач Task API, где оно указывает следующее время (в миллисекундах с начала эпохи), когда запрос, ограниченный по времени, будет снова выполнен, чтобы соответствоватьrequests_per_second. -
failures - (массив) Массив ошибок, если во время процесса возникли непреодолимые ошибки. Если этот массив не пустой, запрос был прерван из-за этих ошибок. Переиндексация реализована с помощью партий, и любая ошибка приводит к прерыванию всего процесса, но все ошибки в текущей партии собираются в массив. Вы можете использовать опцию
conflicts, чтобы предотвратить прерывание переиндексации при конфликтах версий.
Примеры
Переиндексация выбранных документов с запросом
Вы можете ограничить документы, добавив запрос к source. Например, следующий запрос копирует только документы с user.id значения kimchy в my-new-index-000001:
resp = client.reindex(
source={
"index": "my-index-000001",
"query": {
"term": {
"user.id": "kimchy"
}
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'my-index-000001',
query: {
term: {
'user.id' => 'kimchy'
}
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
query: {
term: {
"user.id": "kimchy",
},
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "my-index-000001",
"query": {
"term": {
"user.id": "kimchy"
}
}
},
"dest": {
"index": "my-new-index-000001"
}
} Переиндексация выбранных документов с max_docs
Вы можете ограничить количество обрабатываемых документов, установив max_docs. Например, этот запрос копирует один документ из my-index-000001 в my-new-index-000001:
resp = client.reindex(
max_docs=1,
source={
"index": "my-index-000001"
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
max_docs: 1,
source: {
index: 'my-index-000001'
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
max_docs: 1,
source: {
index: "my-index-000001",
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"max_docs": 1,
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001"
}
} Переиндексация из нескольких источников
Атрибут index в source может быть списком, что позволяет копировать из множества источников в одном запросе. Это скопирует документы из индексов my-index-000001 и my-index-000002:
resp = client.reindex(
source={
"index": [
"my-index-000001",
"my-index-000002"
]
},
dest={
"index": "my-new-index-000002"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: [
'my-index-000001',
'my-index-000002'
]
},
dest: {
index: 'my-new-index-000002'
}
}
)
puts response const response = await client.reindex({
source: {
index: ["my-index-000001", "my-index-000002"],
},
dest: {
index: "my-new-index-000002",
},
});
console.log(response); POST _reindex
{
"source": {
"index": ["my-index-000001", "my-index-000002"]
},
"dest": {
"index": "my-new-index-000002"
}
} API переиндексации не пытается обрабатывать коллизии ID, поэтому последний записанный документ «выиграет», но порядок обычно непредсказуем, поэтому полагаться на это поведение не рекомендуется. Вместо этого убедитесь, что ID уникальны, используя скрипт.
Переиндексация выбранных полей с фильтром источника
Вы можете использовать фильтрацию источника для переиндексации подмножества полей в исходных документах. Например, следующий запрос переиндексирует только поля user.id и _doc каждого документа:
resp = client.reindex(
source={
"index": "my-index-000001",
"_source": [
"user.id",
"_doc"
]
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'my-index-000001',
_source: [
'user.id',
'_doc'
]
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
_source: ["user.id", "_doc"],
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "my-index-000001",
"_source": ["user.id", "_doc"]
},
"dest": {
"index": "my-new-index-000001"
}
} Переиндексация для изменения имени поля
_reindex можно использовать для создания копии индекса с переименованными полями. Предположим, вы создаете индекс, содержащий документы такого вида:
resp = client.index(
index="my-index-000001",
id="1",
refresh=True,
document={
"text": "words words",
"flag": "foo"
},
)
print(resp) response = client.index(
index: 'my-index-000001',
id: 1,
refresh: true,
body: {
text: 'words words',
flag: 'foo'
}
)
puts response const response = await client.index({
index: "my-index-000001",
id: 1,
refresh: "true",
document: {
text: "words words",
flag: "foo",
},
});
console.log(response); POST my-index-000001/_doc/1?refresh
{
"text": "words words",
"flag": "foo"
} но вам не нравится имя flag и вы хотите заменить его на tag. _reindex может создать для вас другой индекс:
resp = client.reindex(
source={
"index": "my-index-000001"
},
dest={
"index": "my-new-index-000001"
},
script={
"source": "ctx._source.tag = ctx._source.remove(\"flag\")"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'my-index-000001'
},
dest: {
index: 'my-new-index-000001'
},
script: {
source: 'ctx._source.tag = ctx._source.remove("flag")'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
},
dest: {
index: "my-new-index-000001",
},
script: {
source: 'ctx._source.tag = ctx._source.remove("flag")',
},
});
console.log(response); POST _reindex
{
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001"
},
"script": {
"source": "ctx._source.tag = ctx._source.remove(\"flag\")"
}
} Теперь вы можете получить новый документ:
resp = client.get(
index="my-new-index-000001",
id="1",
)
print(resp) response = client.get( index: 'my-new-index-000001', id: 1 ) puts response
const response = await client.get({
index: "my-new-index-000001",
id: 1,
});
console.log(response); GET my-new-index-000001/_doc/1
что вернет:
{
"found": true,
"_id": "1",
"_index": "my-new-index-000001",
"_version": 1,
"_seq_no": 44,
"_primary_term": 1,
"_source": {
"text": "words words",
"tag": "foo"
}
} Переиндексация ежедневных индексов
Вы можете использовать _reindex в сочетании с Painless, чтобы переиндексировать ежедневные индексы, чтобы применить новую шаблон к существующим документам.
Предположим, у вас есть индексы, содержащие документы, подобные:
$params = [
'index' => 'metricbeat-2016.05.30',
'id' => '1',
'body' => [
'system.cpu.idle.pct' => 0.908,
],
];
$response = $client->index($params);
$params = [
'index' => 'metricbeat-2016.05.31',
'id' => '1',
'body' => [
'system.cpu.idle.pct' => 0.105,
],
];
$response = $client->index($params); resp = client.index(
index="metricbeat-2016.05.30",
id="1",
refresh=True,
document={
"system.cpu.idle.pct": 0.908
},
)
print(resp)
resp1 = client.index(
index="metricbeat-2016.05.31",
id="1",
refresh=True,
document={
"system.cpu.idle.pct": 0.105
},
)
print(resp1) response = client.index(
index: 'metricbeat-2016.05.30',
id: 1,
refresh: true,
body: {
'system.cpu.idle.pct' => 0.908
}
)
puts response
response = client.index(
index: 'metricbeat-2016.05.31',
id: 1,
refresh: true,
body: {
'system.cpu.idle.pct' => 0.105
}
)
puts response {
res, err := es.Index(
"metricbeat-2016.05.30",
strings.NewReader(`{
"system.cpu.idle.pct": 0.908
}`),
es.Index.WithDocumentID("1"),
es.Index.WithRefresh("true"),
es.Index.WithPretty(),
)
fmt.Println(res, err)
}
{
res, err := es.Index(
"metricbeat-2016.05.31",
strings.NewReader(`{
"system.cpu.idle.pct": 0.105
}`),
es.Index.WithDocumentID("1"),
es.Index.WithRefresh("true"),
es.Index.WithPretty(),
)
fmt.Println(res, err)
} const response = await client.index({
index: "metricbeat-2016.05.30",
id: 1,
refresh: "true",
document: {
"system.cpu.idle.pct": 0.908,
},
});
console.log(response);
const response1 = await client.index({
index: "metricbeat-2016.05.31",
id: 1,
refresh: "true",
document: {
"system.cpu.idle.pct": 0.105,
},
});
console.log(response1); PUT metricbeat-2016.05.30/_doc/1?refresh
{"system.cpu.idle.pct": 0.908}
PUT metricbeat-2016.05.31/_doc/1?refresh
{"system.cpu.idle.pct": 0.105} Новый шаблон для индексов metricbeat-* уже загружен в Elasticsearch, но он применяется только к вновь созданным индексам. Painless можно использовать для переиндексации существующих документов и применения нового шаблона.
Нижеприведенный скрипт извлекает дату из имени индекса и создает новый индекс с добавленным -1. Все данные из metricbeat-2016.05.31 будут переиндексированы в metricbeat-2016.05.31-1.
$params = [
'body' => [
'source' => [
'index' => 'metricbeat-*',
],
'dest' => [
'index' => 'metricbeat',
],
'script' => [
'lang' => 'painless',
'source' => 'ctx._index = \'metricbeat-\' + (ctx._index.substring(\'metricbeat-\'.length(), ctx._index.length())) + \'-1\'',
],
],
];
$response = $client->reindex($params); resp = client.reindex(
source={
"index": "metricbeat-*"
},
dest={
"index": "metricbeat"
},
script={
"lang": "painless",
"source": "ctx._index = 'metricbeat-' + (ctx._index.substring('metricbeat-'.length(), ctx._index.length())) + '-1'"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'metricbeat-*'
},
dest: {
index: 'metricbeat'
},
script: {
lang: 'painless',
source: "ctx._index = 'metricbeat-' + (ctx._index.substring('metricbeat-'.length(), ctx._index.length())) + '-1'"
}
}
)
puts response res, err := es.Reindex(
strings.NewReader(`{
"source": {
"index": "metricbeat-*"
},
"dest": {
"index": "metricbeat"
},
"script": {
"lang": "painless",
"source": "ctx._index = 'metricbeat-' + (ctx._index.substring('metricbeat-'.length(), ctx._index.length())) + '-1'"
}
}`))
fmt.Println(res, err) const response = await client.reindex({
source: {
index: "metricbeat-*",
},
dest: {
index: "metricbeat",
},
script: {
lang: "painless",
source:
"ctx._index = 'metricbeat-' + (ctx._index.substring('metricbeat-'.length(), ctx._index.length())) + '-1'",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "metricbeat-*"
},
"dest": {
"index": "metricbeat"
},
"script": {
"lang": "painless",
"source": "ctx._index = 'metricbeat-' + (ctx._index.substring('metricbeat-'.length(), ctx._index.length())) + '-1'"
}
} Все документы из предыдущих индексов metricbeat теперь можно найти в индексах *-1.
$params = [
'index' => 'metricbeat-2016.05.30-1',
'id' => '1',
];
$response = $client->get($params);
$params = [
'index' => 'metricbeat-2016.05.31-1',
'id' => '1',
];
$response = $client->get($params); resp = client.get(
index="metricbeat-2016.05.30-1",
id="1",
)
print(resp)
resp1 = client.get(
index="metricbeat-2016.05.31-1",
id="1",
)
print(resp1) response = client.get( index: 'metricbeat-2016.05.30-1', id: 1 ) puts response response = client.get( index: 'metricbeat-2016.05.31-1', id: 1 ) puts response
{
res, err := es.Get("metricbeat-2016.05.30-1", "1", es.Get.WithPretty())
fmt.Println(res, err)
}
{
res, err := es.Get("metricbeat-2016.05.31-1", "1", es.Get.WithPretty())
fmt.Println(res, err)
} const response = await client.get({
index: "metricbeat-2016.05.30-1",
id: 1,
});
console.log(response);
const response1 = await client.get({
index: "metricbeat-2016.05.31-1",
id: 1,
});
console.log(response1); GET metricbeat-2016.05.30-1/_doc/1 GET metricbeat-2016.05.31-1/_doc/1
Предыдущий метод также можно использовать в сочетании с изменением имени поля, чтобы загрузить только существующие данные в новый индекс и переименовать любые поля при необходимости.
Извлечение случайной подвыборки источника
_reindex можно использовать для извлечения случайной подвыборки источника для тестирования:
resp = client.reindex(
max_docs=10,
source={
"index": "my-index-000001",
"query": {
"function_score": {
"random_score": {},
"min_score": 0.9
}
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
max_docs: 10,
source: {
index: 'my-index-000001',
query: {
function_score: {
random_score: {},
min_score: 0.9
}
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
max_docs: 10,
source: {
index: "my-index-000001",
query: {
function_score: {
random_score: {},
min_score: 0.9,
},
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"max_docs": 10,
"source": {
"index": "my-index-000001",
"query": {
"function_score" : {
"random_score" : {},
"min_score" : 0.9
}
}
},
"dest": {
"index": "my-new-index-000001"
}
} | Вам может потребоваться скорректировать |
Изменение документов во время переиндексации
Как и _update_by_query, _reindex поддерживает скрипт, который изменяет документ. В отличие от _update_by_query, скрипт разрешено изменять метаданные документа. В этом примере увеличивается версия исходного документа:
resp = client.reindex(
source={
"index": "my-index-000001"
},
dest={
"index": "my-new-index-000001",
"version_type": "external"
},
script={
"source": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
"lang": "painless"
},
)
print(resp) response = client.reindex(
body: {
source: {
index: 'my-index-000001'
},
dest: {
index: 'my-new-index-000001',
version_type: 'external'
},
script: {
source: "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
lang: 'painless'
}
}
)
puts response const response = await client.reindex({
source: {
index: "my-index-000001",
},
dest: {
index: "my-new-index-000001",
version_type: "external",
},
script: {
source:
"if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
lang: "painless",
},
});
console.log(response); POST _reindex
{
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001",
"version_type": "external"
},
"script": {
"source": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
"lang": "painless"
}
} Как и в _update_by_query, вы можете установить ctx.op, чтобы изменить операцию, выполняемую на целевом индексе:
-
noop - Установите
ctx.op = "noop", если ваш скрипт решил, что документ не нужно индексировать в целевом индексе. Эта бездействующая операция будет отражена в счётчикеnoopв теле ответа. -
delete - Установите
ctx.op = "delete", если ваш скрипт решил, что документ необходимо удалить из целевого индекса. Удаление будет отражено в счётчикеdeletedв теле ответа.
Установка ctx.op на любое другое значение приведет к ошибке, как и установка любого другого поля в ctx.
Подумайте о возможностях! Но будьте осторожны; вы можете изменить:
-
_id -
_index -
_version -
_routing
Установка _version на null или удаление его из карты ctx аналогично тому, как вы не отправляете версию в запросе индексирования; это приведет к перезаписи документа в целевом индексе независимо от версии в целевом индексе или типа версии, используемого в запросе _reindex.
Переиндексация с удалённого узла
Переиндексация поддерживает переиндексацию с удалённого кластера Elasticsearch:
resp = client.reindex(
source={
"remote": {
"host": "http://otherhost:9200",
"username": "user",
"password": "pass"
},
"index": "my-index-000001",
"query": {
"match": {
"test": "data"
}
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
source: {
remote: {
host: 'http://otherhost:9200',
username: 'user',
password: 'pass'
},
index: 'my-index-000001',
query: {
match: {
test: 'data'
}
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
remote: {
host: "http://otherhost:9200",
username: "user",
password: "pass",
},
index: "my-index-000001",
query: {
match: {
test: "data",
},
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
"username": "user",
"password": "pass"
},
"index": "my-index-000001",
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "my-new-index-000001"
}
} Параметр host должен содержать схему, хост, порт (например, https://otherhost:9200), и необязательный путь (например, https://otherhost:9200/proxy). Параметры username и password необязательны, и при их наличии _reindex будет подключаться к удалённому узлу Elasticsearch с использованием аутентификации по логину и паролю. Обязательно используйте https при использовании аутентификации по логину и паролю, чтобы пароль не был отправлен в открытом виде. Доступно множество настроек для настройки поведения подключения https.
При использовании Elastic Cloud также возможно аутентифицироваться с удалённым кластером с помощью валидного API ключа:
resp = client.reindex(
source={
"remote": {
"host": "http://otherhost:9200",
"headers": {
"Authorization": "ApiKey API_KEY_VALUE"
}
},
"index": "my-index-000001",
"query": {
"match": {
"test": "data"
}
}
},
dest={
"index": "my-new-index-000001"
},
)
print(resp) response = client.reindex(
body: {
source: {
remote: {
host: 'http://otherhost:9200',
headers: {
"Authorization": 'ApiKey API_KEY_VALUE'
}
},
index: 'my-index-000001',
query: {
match: {
test: 'data'
}
}
},
dest: {
index: 'my-new-index-000001'
}
}
)
puts response const response = await client.reindex({
source: {
remote: {
host: "http://otherhost:9200",
headers: {
Authorization: "ApiKey API_KEY_VALUE",
},
},
index: "my-index-000001",
query: {
match: {
test: "data",
},
},
},
dest: {
index: "my-new-index-000001",
},
});
console.log(response); POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
"headers": {
"Authorization": "ApiKey API_KEY_VALUE"
}
},
"index": "my-index-000001",
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "my-new-index-000001"
}
} Удалённые узлы должны быть явно разрешены в elasticsearch.yml с использованием свойства reindex.remote.whitelist. Оно может быть установлено в виде списка разрешённых удалённых host и port комбинаций, разделённых запятыми. Схема игнорируется, используются только хост и порт. Например:
reindex.remote.whitelist: [otherhost:9200, another:9200, 127.0.10.*:9200, localhost:*"]
Список разрешённых хостов должен быть настроен на всех узлах, которые будут координировать переиндексацию.
Эта функция должна работать с удалёнными кластерами любой версии Elasticsearch, которую вы, вероятно, найдёте. Это позволит вам выполнить апгрейд с любой версии Elasticsearch до текущей версии путём переиндексации с кластера старой версии.
Elasticsearch не поддерживает обратную совместимость между основными версиями. Например, вы не можете переиндексировать данные из кластера 7.x в кластер 6.x.
Для разрешения запросов, отправляемых в более старые версии Elasticsearch, параметр query отправляется непосредственно на удалённый узел без проверки или изменения.
Переиндексация с удалённых кластеров не поддерживает ручную или автоматическую нарезку.
Переиндексация с удалённого сервера использует буфер в оперативной памяти, по умолчанию максимальный размер которого составляет 100 МБ. Если удалённый индекс содержит очень большие документы, вам потребуется использовать меньший размер пакета. В примере ниже размер пакета установлен в 10, что очень, очень мало.
POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
...
},
"index": "source",
"size": 10,
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "dest"
}
} Также возможно установить таймаут чтения сокета для удалённого соединения с помощью поля socket_timeout, а таймаут подключения с помощью поля connect_timeout. Оба по умолчанию составляют 30 секунд. В этом примере таймаут чтения сокета установлен на одну минуту, а таймаут подключения на 10 секунд:
POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
...,
"socket_timeout": "1m",
"connect_timeout": "10s"
},
"index": "source",
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "dest"
}
} Настройка параметров SSL
Переиндексация с удалённого узла поддерживает настраиваемые параметры SSL. Эти параметры должны быть указаны в файле elasticsearch.yml, за исключением параметров безопасности, которые вы добавляете в хранилище ключей Elasticsearch. Настройка SSL в теле запроса _reindex невозможна. Обратитесь к настройкам переиндексации.
© 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/8.17/docs-reindex.html