Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›REST API ›Документация по API документов

API массовой загрузки

Справочник нового API

Для получения самых последних данных API обратитесь к Документам API.

Выполняет несколько операций индексирования или удаления в одном API-запросе. Это уменьшает накладные расходы и может значительно увеличить скорость индексирования.

$params = [
    'body' => [
        [
            'index' => [
                '_index' => 'test',
                '_id' => '1',
            ],
        ],
        [
            'field1' => 'value1',
        ],
        [
            'delete' => [
                '_index' => 'test',
                '_id' => '2',
            ],
        ],
        [
            'create' => [
                '_index' => 'test',
                '_id' => '3',
            ],
        ],
        [
            'field1' => 'value3',
        ],
        [
            'update' => [
                '_id' => '1',
                '_index' => 'test',
            ],
        ],
        [
            'doc' => [
                'field2' => 'value2',
            ],
        ],
    ],
];
$response = $client->bulk($params);
resp = client.bulk(
    operations=[
        {
            "index": {
                "_index": "test",
                "_id": "1"
            }
        },
        {
            "field1": "value1"
        },
        {
            "delete": {
                "_index": "test",
                "_id": "2"
            }
        },
        {
            "create": {
                "_index": "test",
                "_id": "3"
            }
        },
        {
            "field1": "value3"
        },
        {
            "update": {
                "_id": "1",
                "_index": "test"
            }
        },
        {
            "doc": {
                "field2": "value2"
            }
        }
    ],
)
print(resp)
response = client.bulk(
  body: [
    {
      index: {
        _index: 'test',
        _id: '1'
      }
    },
    {
      "field1": 'value1'
    },
    {
      delete: {
        _index: 'test',
        _id: '2'
      }
    },
    {
      create: {
        _index: 'test',
        _id: '3'
      }
    },
    {
      "field1": 'value3'
    },
    {
      update: {
        _id: '1',
        _index: 'test'
      }
    },
    {
      doc: {
        "field2": 'value2'
      }
    }
  ]
)
puts response
res, err := es.Bulk(
	strings.NewReader(`
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
`),
)
fmt.Println(res, err)
const response = await client.bulk({
  operations: [
    {
      index: {
        _index: "test",
        _id: "1",
      },
    },
    {
      field1: "value1",
    },
    {
      delete: {
        _index: "test",
        _id: "2",
      },
    },
    {
      create: {
        _index: "test",
        _id: "3",
      },
    },
    {
      field1: "value3",
    },
    {
      update: {
        _id: "1",
        _index: "test",
      },
    },
    {
      doc: {
        field2: "value2",
      },
    },
  ],
});
console.log(response);
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

Запрос

POST /_bulk

POST /<target>/_bulk

Предварительные условия

  • Если функции безопасности Elasticsearch включены, у вас должны быть следующие права доступа к индексам для целевого потока данных, индекса или псевдонима индекса:

    • Для использования действия create, у вас должен быть create_doc, create, index или write право доступа к индексу. Потоки данных поддерживают только действие create.
    • Для использования действия index, у вас должен быть create, index или write право доступа к индексу.
    • Для использования действия delete, у вас должен быть delete или write право доступа к индексу.
    • Для использования действия update, у вас должен быть index или write право доступа к индексу.
    • Для автоматического создания потока данных или индекса с помощью запроса API массового выполнения, у вас должен быть auto_configure, create_index или manage право доступа к индексу.
    • Чтобы сделать результат операции массового выполнения видимым для поиска с помощью параметра refresh, у вас должен быть maintenance или manage право доступа к индексу.
  • Автоматическое создание потока данных требует соответствующей шаблона индекса с включённым потоком данных. См. Настройка потока данных.

Описание

Предоставляет способ выполнения нескольких действий index, create, delete и update в одном запросе.

Действия задаются в теле запроса с использованием структуры JSON с разделителями строк (NDJSON):

action_and_meta_data\n
optional_source\n
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n

Действия index и create ожидают исходный документ на следующей строке и имеют ту же семантику, что и параметр op_type в стандартном API индексирования: create возвращает ошибку, если документ с тем же ID уже существует в целевом индексе, index добавляет или заменяет документ по мере необходимости.

Потоки данных поддерживают только действие create. Чтобы обновить или удалить документ в потоке данных, необходимо обратиться к индексу, который содержит документ. См. Обновление или удаление документов в базовом индексе.

update ожидает, что частичный документ, upsert, скрипт и его параметры будут указаны на следующей строке.

delete не ожидает исходный документ на следующей строке и имеет ту же семантику, что и стандартный API удаления.

Последняя строка данных должна заканчиваться символом новой строки \n. Каждый символ новой строки может предваряться символом возврата каретки \r. При отправке данных NDJSON на конечную точку _bulk используйте заголовок Content-Type со значением application/json или application/x-ndjson.

Поскольку этот формат использует буквальные \n в качестве разделителей, убедитесь, что JSON-действия и источники не отформатированы красиво.

Если вы предоставите значение <target> в пути запроса, оно используется для любых действий, которые не явно не указывают аргумент _index.

Примечание о формате: основная идея заключается в том, чтобы сделать обработку этой информации максимально быстрой. Поскольку некоторые действия перенаправляются на другие фрагменты на других узлах, только action_meta_data анализируются на стороне принимающего узла.

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

Нет «правильного» количества действий для выполнения в одном запросе массового выполнения. Экспериментируйте с разными настройками, чтобы найти оптимальный размер для вашей конкретной рабочей нагрузки. Обратите внимание, что Elasticsearch по умолчанию ограничивает максимальный размер запроса HTTP до 100mb, поэтому клиенты должны убедиться, что ни один запрос не превышает этот размер. Невозможно индексировать один документ, размер которого превышает предел, поэтому вы должны предварительно обработать такие документы, разделив их на более мелкие части, прежде чем отправлять их в Elasticsearch. Например, разделите документы на страницы или главы перед их индексированием или храните исходные двоичные данные в системе вне Elasticsearch, заменяя исходные данные ссылкой на внешнюю систему в документах, которые вы отправляете в Elasticsearch.

Поддержка массовых запросов клиентскими библиотеками

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

Go
См. esutil.BulkIndexer
Perl
См. Search::Elasticsearch::Client::5_0::Bulk и Search::Elasticsearch::Client::5_0::Scroll
Python
См. elasticsearch.helpers.*
JavaScript
См. client.helpers.*
.NET
См. BulkAllObservable
PHP
См. Массовая индексация
Отправка массовых запросов с помощью cURL

Если вы предоставляете текстовый файл для curl, вы должны использовать флаг --data-binary вместо обычного -d. Последний не сохраняет символы новой строки. Пример:

$ cat requests
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
$ curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/_bulk --data-binary "@requests"; echo
{"took":7, "errors": false, "items":[{"index":{"_index":"test","_id":"1","_version":1,"result":"created","forced_refresh":false}}]}
Оптимистический контроль конкуретности

Каждое действие index и delete в рамках API массового выполнения может включать параметры if_seq_no и if_primary_term в соответствующих строках действия и метаданных. Параметры if_seq_no и if_primary_term управляют выполнением операций, основываясь на последних изменениях существующих документов. Дополнительные сведения см. в разделе Оптимистический контроль конкуретности.

Версионирование

Каждый элемент массового запроса может содержать значение версии с помощью поля version. Оно автоматически следует поведению операции индексирования/удаления на основе сопоставления _version. Также поддерживается version_type (см. версионирование).

Маршрутизация

Каждый элемент массового запроса может содержать значение маршрутизации с помощью поля routing. Оно автоматически следует поведению операции индексирования/удаления на основе сопоставления _routing.

Потоки данных не поддерживают пользовательскую маршрутизацию, если она не была настроена с помощью параметра allow_custom_routing в шаблоне.

Ожидание активных фрагментов

При выполнении массовых запросов вы можете установить параметр wait_for_active_shards, чтобы потребовать минимальное количество активных копий фрагментов перед началом обработки массового запроса. Дополнительные сведения и пример использования см. в разделе здесь.

Обновление

Управление временем, когда изменения, внесённые этим запросом, становятся видимыми для поиска. См. refresh.

Только фрагменты, которые получают массовый запрос, будут затронуты параметром refresh. Представьте массовый запрос с тремя документами, которые случайно маршрутизированы на разные фрагменты в индексе с пятью фрагментами. Запрос будет ожидать обновления только этих трёх фрагментов. Два других фрагмента, составляющие индекс, вообще не участвуют в запросе _bulk.

Безопасность

См. Управление доступом на основе URL.

Параметры пути

<target>
(Необязательно, строка) Имя потока данных, индекса или псевдонима индекса для выполнения массовых операций.

Параметры запроса

list_executed_pipelines
(Необязательно, булево) Если true, ответ будет содержать конвейеры обработки, которые были выполнены для каждого index или create. По умолчанию false.
pipeline
(Необязательно, строка) Идентификатор конвейера, используемого для предварительной обработки входящих документов. Если для индекса указан конвейер обработки по умолчанию, то установка значения в _none отключит конвейер обработки по умолчанию для этого запроса. Если настроен конечный конвейер, он всегда будет выполняться независимо от значения этого параметра.
refresh
(Необязательно, перечисление) Если true, Elasticsearch обновляет затронутые фрагменты, чтобы сделать эту операцию видимой для поиска, если wait_for, то дождитесь обновления, чтобы сделать эту операцию видимой для поиска, если false, то ничего не делайте с обновлениями. Допустимые значения: true, false, wait_for. По умолчанию: false.
require_alias
(Необязательно, булево) Если true, действия запроса должны быть направлены на псевдоним индекса. По умолчанию false.
routing
(Необязательно, строка) Пользовательское значение, используемое для маршрутизации операций в определенный фрагмент.
_source
(Необязательно, строка) True или false для возврата поля _source или нет, или список полей для возврата.
_source_excludes

(Необязательно, строка) Список полей источника, разделенных запятыми, которые следует исключить из ответа.

Также можно использовать этот параметр для исключения полей из набора, указанного в параметре запроса _source_includes.

Если параметр _source равен false, этот параметр игнорируется.

_source_includes

(Необязательно, строка) Список полей источника, разделенных запятыми, которые следует включить в ответ.

Если этот параметр указан, возвращаются только эти поля источника. Можно исключить поля из этого набора, используя параметр запроса _source_excludes.

Если параметр _source равен false, этот параметр игнорируется.

timeout

(Необязательно, единицы времени) Период, в течение которого каждое действие ожидает следующих операций:

  • Автоматическое создание индексов
  • Обновления динамического сопоставления
  • Ожидание активных фрагментов

По умолчанию 1m (одна минута). Это гарантирует, что Elasticsearch подождёт, по крайней мере, заданное время, прежде чем завершится с ошибкой. Фактическое время ожидания может быть больше, особенно при наличии нескольких ожиданий.

wait_for_active_shards

(Необязательно, строка) Количество копий каждого фрагмента, которое должно быть активным, прежде чем продолжить операцию. Установите значение в all или любое неотрицательное целое число до общего количества копий каждого фрагмента в индексе (number_of_replicas+1). По умолчанию 1, что означает ожидание активации только каждого первичного фрагмента.

См. Активные фрагменты.

Тело запроса

Тело запроса содержит список, разделенный символом новой строки, действий create, delete, index и update и связанных с ними исходных данных.

create

(Необязательно, строка) Индексирует указанный документ, если он ещё не существует. Следующая строка должна содержать исходные данные для индексирования.

_index
(Необязательно, строка) Имя потока данных, индекса или псевдонима индекса для выполнения действия. Этот параметр обязателен, если в пути запроса не указан <target>.
_id
(Необязательно, строка) Идентификатор документа. Если идентификатор не указан, идентификатор документа генерируется автоматически.
list_executed_pipelines
(Необязательно, булево) Если true, ответ будет содержать конвейеры обработки, которые были выполнены. По умолчанию false.
require_alias
(Необязательно, булево) Если true, действие должно быть направлено на псевдоним индекса. По умолчанию false.
dynamic_templates
(Необязательно, карта) Карта, отображающая полное имя полей на имя динамических шаблонов. По умолчанию пустая карта. Если имя совпадает с именем динамического шаблона, этот шаблон применяется независимо от других условий соответствия, определённых в шаблоне. И если поле уже определено в сопоставлении, то этот параметр не будет использован.
delete

(Необязательно, строка) Удаляет указанный документ из индекса.

_index
(Необязательно, строка) Имя индекса или псевдонима индекса для выполнения действия. Этот параметр обязателен, если в пути запроса не указан <target>.
_id
(Обязательно, строка) Идентификатор документа.
require_alias
(Необязательно, булево) Если true, действие должно быть направлено на псевдоним индекса. По умолчанию false.
index

(Необязательно, строка) Индексирует указанный документ. Если документ существует, заменяет документ и увеличивает версию. Следующая строка должна содержать исходные данные для индексирования.

_index
(Необязательно, строка) Имя индекса или псевдонима индекса для выполнения действия. Этот параметр обязателен, если в пути запроса не указан <target>.
_id
(Необязательно, строка) Идентификатор документа. Если идентификатор не указан, идентификатор документа генерируется автоматически.
list_executed_pipelines
(Необязательно, булево) Если true, ответ будет содержать конвейеры обработки, которые были выполнены. По умолчанию false.
require_alias
(Необязательно, булево) Если true, действие должно быть направлено на псевдоним индекса. По умолчанию false.
dynamic_templates
(Необязательно, карта) Карта, отображающая полное имя полей на имя динамических шаблонов. По умолчанию пустая карта. Если имя совпадает с именем динамического шаблона, этот шаблон применяется независимо от других условий соответствия, определённых в шаблоне. И если поле уже определено в сопоставлении, то этот параметр не будет использован.
update

(Необязательно, строка) Выполняет частичное обновление документа. Следующая строка должна содержать частичный документ и параметры обновления.

_index
(Необязательно, строка) Имя индекса или псевдонима индекса для выполнения действия. Этот параметр обязателен, если в пути запроса не указан <target>.
_id
(Обязательно, строка) Идентификатор документа.
require_alias
(Необязательно, булево) Если true, действие должно быть направлено на псевдоним индекса. По умолчанию false.
doc
(Необязательно, объект) Частичный документ для индексирования. Обязателен для операций update.
<fields>
(Необязательно, объект) Источник документа для индексирования. Обязателен для операций create и index.

Тело ответа

Ответ API для массовых операций содержит отдельные результаты каждой операции в запросе, возвращаемые в порядке отправки. Успех или неудача одной операции не влияют на другие операции в запросе.

took
(целое число) Время обработки массового запроса в миллисекундах.
errors
(Булево) Если true, одна или несколько операций в массовом запросе не завершились успешно.
items

(массив объектов) Содержит результат каждой операции в массовом запросе в порядке их отправки.

Свойства объектов items
<action>

(объект) Имя параметра — действие, связанное с операцией. Возможные значения: create, delete, index и update.

Значение параметра — объект, содержащий информацию для соответствующей операции.

Свойства <action>
_index
(строка) Имя индекса, связанного с операцией. Если операция была направлена на поток данных, это базовый индекс, в который был записан документ.
_id
(целое число) ID документа, связанного с операцией.
_version

(целое число) Версия документа, связанная с операцией. Версия документа увеличивается каждый раз при обновлении документа.

Этот параметр возвращается только для успешных действий.

result
(строка) Результат операции. Успешные значения: created, deleted и updated. Другие допустимые значения: noop и not_found.
_shards

(объект) Содержит информацию о фрагментах для операции.

Этот параметр возвращается только для успешных операций.

Свойства _shards
total
(целое число) Количество фрагментов, на которых операция пыталась выполнить действие.
successful
(целое число) Количество фрагментов, на которых операция выполнилась успешно.
failed
(целое число) Количество фрагментов, на которых операция пыталась выполнить действие, но потерпела неудачу.
_seq_no

(целое число) Номер последовательности, назначенный документу для операции. Номера последовательности используются для обеспечения того, что более старая версия документа не перезаписывает более новую версию. См. Контроль одновременного доступа.

Этот параметр возвращается только для успешных операций.

_primary_term

(целое число) Основной термин, назначенный документу для операции. См. Контроль одновременного доступа.

Этот параметр возвращается только для успешных операций.

status
(целое число) Код HTTP-статуса, возвращённый для операции.
error

(объект) Содержит дополнительную информацию о неудачной операции.

Параметр возвращается только для неудачных операций.

Свойства error
type
(строка) Тип ошибки для операции.
reason
(строка) Причина неудачной операции.
index_uuid
(строка) Универсально уникальный идентификатор (UUID) индекса, связанного с неудачной операцией.
shard
(строка) ID фрагмента, связанного с неудачной операцией.
index
(строка) Имя индекса, связанного с неудачной операцией. Если операция была направлена на поток данных, это базовый индекс, в который пытались записать документ.

Примеры

$params = [
    'body' => [
        [
            'index' => [
                '_index' => 'test',
                '_id' => '1',
            ],
        ],
        [
            'field1' => 'value1',
        ],
        [
            'delete' => [
                '_index' => 'test',
                '_id' => '2',
            ],
        ],
        [
            'create' => [
                '_index' => 'test',
                '_id' => '3',
            ],
        ],
        [
            'field1' => 'value3',
        ],
        [
            'update' => [
                '_id' => '1',
                '_index' => 'test',
            ],
        ],
        [
            'doc' => [
                'field2' => 'value2',
            ],
        ],
    ],
];
$response = $client->bulk($params);
resp = client.bulk(
    operations=[
        {
            "index": {
                "_index": "test",
                "_id": "1"
            }
        },
        {
            "field1": "value1"
        },
        {
            "delete": {
                "_index": "test",
                "_id": "2"
            }
        },
        {
            "create": {
                "_index": "test",
                "_id": "3"
            }
        },
        {
            "field1": "value3"
        },
        {
            "update": {
                "_id": "1",
                "_index": "test"
            }
        },
        {
            "doc": {
                "field2": "value2"
            }
        }
    ],
)
print(resp)
response = client.bulk(
  body: [
    {
      index: {
        _index: 'test',
        _id: '1'
      }
    },
    {
      "field1": 'value1'
    },
    {
      delete: {
        _index: 'test',
        _id: '2'
      }
    },
    {
      create: {
        _index: 'test',
        _id: '3'
      }
    },
    {
      "field1": 'value3'
    },
    {
      update: {
        _id: '1',
        _index: 'test'
      }
    },
    {
      doc: {
        "field2": 'value2'
      }
    }
  ]
)
puts response
res, err := es.Bulk(
	strings.NewReader(`
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
`),
)
fmt.Println(res, err)
const response = await client.bulk({
  operations: [
    {
      index: {
        _index: "test",
        _id: "1",
      },
    },
    {
      field1: "value1",
    },
    {
      delete: {
        _index: "test",
        _id: "2",
      },
    },
    {
      create: {
        _index: "test",
        _id: "3",
      },
    },
    {
      field1: "value3",
    },
    {
      update: {
        _id: "1",
        _index: "test",
      },
    },
    {
      doc: {
        field2: "value2",
      },
    },
  ],
});
console.log(response);
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

API возвращает следующий результат:

{
   "took": 30,
   "errors": false,
   "items": [
      {
         "index": {
            "_index": "test",
            "_id": "1",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 0,
            "_primary_term": 1
         }
      },
      {
         "delete": {
            "_index": "test",
            "_id": "2",
            "_version": 1,
            "result": "not_found",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 404,
            "_seq_no" : 1,
            "_primary_term" : 2
         }
      },
      {
         "create": {
            "_index": "test",
            "_id": "3",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 2,
            "_primary_term" : 3
         }
      },
      {
         "update": {
            "_index": "test",
            "_id": "1",
            "_version": 2,
            "result": "updated",
            "_shards": {
                "total": 2,
                "successful": 1,
                "failed": 0
            },
            "status": 200,
            "_seq_no" : 3,
            "_primary_term" : 4
         }
      }
   ]
}
Пример массового обновления

При использовании действия update, retry_on_conflict можно использовать в качестве поля самого действия (а не в дополнительной строке полезной нагрузки), чтобы указать, сколько раз обновление должно быть повторено в случае конфликта версий.

Полезная нагрузка действия update поддерживает следующие опции: doc (частичный документ), upsert, doc_as_upsert, script, params (для скрипта), lang (для скрипта) и _source. Подробности об опциях см. в документации по обновлению. Пример с действиями обновления:

$params = [
    'body' => [
        [
            'update' => [
                '_id' => '1',
                '_index' => 'index1',
                'retry_on_conflict' => 3,
            ],
        ],
        [
            'doc' => [
                'field' => 'value',
            ],
        ],
        [
            'update' => [
                '_id' => '0',
                '_index' => 'index1',
                'retry_on_conflict' => 3,
            ],
        ],
        [
            'script' => [
                'source' => 'ctx._source.counter += params.param1',
                'lang' => 'painless',
                'params' => [
                    'param1' => 1,
                ],
            ],
            'upsert' => [
                'counter' => 1,
            ],
        ],
        [
            'update' => [
                '_id' => '2',
                '_index' => 'index1',
                'retry_on_conflict' => 3,
            ],
        ],
        [
            'doc' => [
                'field' => 'value',
            ],
            'doc_as_upsert' => true,
        ],
        [
            'update' => [
                '_id' => '3',
                '_index' => 'index1',
                '_source' => true,
            ],
        ],
        [
            'doc' => [
                'field' => 'value',
            ],
        ],
        [
            'update' => [
                '_id' => '4',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'field' => 'value',
            ],
            '_source' => true,
        ],
    ],
];
$response = $client->bulk($params);
resp = client.bulk(
    operations=[
        {
            "update": {
                "_id": "1",
                "_index": "index1",
                "retry_on_conflict": 3
            }
        },
        {
            "doc": {
                "field": "value"
            }
        },
        {
            "update": {
                "_id": "0",
                "_index": "index1",
                "retry_on_conflict": 3
            }
        },
        {
            "script": {
                "source": "ctx._source.counter += params.param1",
                "lang": "painless",
                "params": {
                    "param1": 1
                }
            },
            "upsert": {
                "counter": 1
            }
        },
        {
            "update": {
                "_id": "2",
                "_index": "index1",
                "retry_on_conflict": 3
            }
        },
        {
            "doc": {
                "field": "value"
            },
            "doc_as_upsert": True
        },
        {
            "update": {
                "_id": "3",
                "_index": "index1",
                "_source": True
            }
        },
        {
            "doc": {
                "field": "value"
            }
        },
        {
            "update": {
                "_id": "4",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "field": "value"
            },
            "_source": True
        }
    ],
)
print(resp)
response = client.bulk(
  body: [
    {
      update: {
        _id: '1',
        _index: 'index1',
        retry_on_conflict: 3
      }
    },
    {
      doc: {
        field: 'value'
      }
    },
    {
      update: {
        _id: '0',
        _index: 'index1',
        retry_on_conflict: 3
      }
    },
    {
      script: {
        source: 'ctx._source.counter += params.param1',
        lang: 'painless',
        params: {
          "param1": 1
        }
      },
      upsert: {
        counter: 1
      }
    },
    {
      update: {
        _id: '2',
        _index: 'index1',
        retry_on_conflict: 3
      }
    },
    {
      doc: {
        field: 'value'
      },
      doc_as_upsert: true
    },
    {
      update: {
        _id: '3',
        _index: 'index1',
        _source: true
      }
    },
    {
      doc: {
        field: 'value'
      }
    },
    {
      update: {
        _id: '4',
        _index: 'index1'
      }
    },
    {
      doc: {
        field: 'value'
      },
      _source: true
    }
  ]
)
puts response
res, err := es.Bulk(
	strings.NewReader(`
{ "update" : {"_id" : "1", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"} }
{ "update" : { "_id" : "0", "_index" : "index1", "retry_on_conflict" : 3} }
{ "script" : { "source": "ctx._source.counter += params.param1", "lang" : "painless", "params" : {"param1" : 1}}, "upsert" : {"counter" : 1}}
{ "update" : {"_id" : "2", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"}, "doc_as_upsert" : true }
{ "update" : {"_id" : "3", "_index" : "index1", "_source" : true} }
{ "doc" : {"field" : "value"} }
{ "update" : {"_id" : "4", "_index" : "index1"} }
{ "doc" : {"field" : "value"}, "_source": true}
`),
)
fmt.Println(res, err)
const response = await client.bulk({
  operations: [
    {
      update: {
        _id: "1",
        _index: "index1",
        retry_on_conflict: 3,
      },
    },
    {
      doc: {
        field: "value",
      },
    },
    {
      update: {
        _id: "0",
        _index: "index1",
        retry_on_conflict: 3,
      },
    },
    {
      script: {
        source: "ctx._source.counter += params.param1",
        lang: "painless",
        params: {
          param1: 1,
        },
      },
      upsert: {
        counter: 1,
      },
    },
    {
      update: {
        _id: "2",
        _index: "index1",
        retry_on_conflict: 3,
      },
    },
    {
      doc: {
        field: "value",
      },
      doc_as_upsert: true,
    },
    {
      update: {
        _id: "3",
        _index: "index1",
        _source: true,
      },
    },
    {
      doc: {
        field: "value",
      },
    },
    {
      update: {
        _id: "4",
        _index: "index1",
      },
    },
    {
      doc: {
        field: "value",
      },
      _source: true,
    },
  ],
});
console.log(response);
POST _bulk
{ "update" : {"_id" : "1", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"} }
{ "update" : { "_id" : "0", "_index" : "index1", "retry_on_conflict" : 3} }
{ "script" : { "source": "ctx._source.counter += params.param1", "lang" : "painless", "params" : {"param1" : 1}}, "upsert" : {"counter" : 1}}
{ "update" : {"_id" : "2", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"}, "doc_as_upsert" : true }
{ "update" : {"_id" : "3", "_index" : "index1", "_source" : true} }
{ "doc" : {"field" : "value"} }
{ "update" : {"_id" : "4", "_index" : "index1"} }
{ "doc" : {"field" : "value"}, "_source": true}
Пример с неудачными действиями

Следующий массовый запрос API включает операции обновления несуществующих документов.

$params = [
    'body' => [
        [
            'update' => [
                '_id' => '5',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'my_field' => 'foo',
            ],
        ],
        [
            'update' => [
                '_id' => '6',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'my_field' => 'foo',
            ],
        ],
        [
            'create' => [
                '_id' => '7',
                '_index' => 'index1',
            ],
        ],
        [
            'my_field' => 'foo',
        ],
    ],
];
$response = $client->bulk($params);
resp = client.bulk(
    operations=[
        {
            "update": {
                "_id": "5",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "my_field": "foo"
            }
        },
        {
            "update": {
                "_id": "6",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "my_field": "foo"
            }
        },
        {
            "create": {
                "_id": "7",
                "_index": "index1"
            }
        },
        {
            "my_field": "foo"
        }
    ],
)
print(resp)
response = client.bulk(
  body: [
    {
      update: {
        _id: '5',
        _index: 'index1'
      }
    },
    {
      doc: {
        my_field: 'foo'
      }
    },
    {
      update: {
        _id: '6',
        _index: 'index1'
      }
    },
    {
      doc: {
        my_field: 'foo'
      }
    },
    {
      create: {
        _id: '7',
        _index: 'index1'
      }
    },
    {
      my_field: 'foo'
    }
  ]
)
puts response
res, err := es.Bulk(
	strings.NewReader(`
{ "update": {"_id": "5", "_index": "index1"} }
{ "doc": {"my_field": "foo"} }
{ "update": {"_id": "6", "_index": "index1"} }
{ "doc": {"my_field": "foo"} }
{ "create": {"_id": "7", "_index": "index1"} }
{ "my_field": "foo" }
`),
)
fmt.Println(res, err)
const response = await client.bulk({
  operations: [
    {
      update: {
        _id: "5",
        _index: "index1",
      },
    },
    {
      doc: {
        my_field: "foo",
      },
    },
    {
      update: {
        _id: "6",
        _index: "index1",
      },
    },
    {
      doc: {
        my_field: "foo",
      },
    },
    {
      create: {
        _id: "7",
        _index: "index1",
      },
    },
    {
      my_field: "foo",
    },
  ],
});
console.log(response);
POST /_bulk
{ "update": {"_id": "5", "_index": "index1"} }
{ "doc": {"my_field": "foo"} }
{ "update": {"_id": "6", "_index": "index1"} }
{ "doc": {"my_field": "foo"} }
{ "create": {"_id": "7", "_index": "index1"} }
{ "my_field": "foo" }

Поскольку эти операции не могут завершиться успешно, API возвращает ответ с флагом errors со значением true.

Ответ также включает объект error для любых неудачных операций. Объект error содержит дополнительную информацию о сбое, например, тип ошибки и причину.

{
  "took": 486,
  "errors": true,
  "items": [
    {
      "update": {
        "_index": "index1",
        "_id": "5",
        "status": 404,
        "error": {
          "type": "document_missing_exception",
          "reason": "[5]: document missing",
          "index_uuid": "aAsFqTI0Tc2W0LCWgPNrOA",
          "shard": "0",
          "index": "index1"
        }
      }
    },
    {
      "update": {
        "_index": "index1",
        "_id": "6",
        "status": 404,
        "error": {
          "type": "document_missing_exception",
          "reason": "[6]: document missing",
          "index_uuid": "aAsFqTI0Tc2W0LCWgPNrOA",
          "shard": "0",
          "index": "index1"
        }
      }
    },
    {
      "create": {
        "_index": "index1",
        "_id": "7",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 0,
        "_primary_term": 1,
        "status": 201
      }
    }
  ]
}

Чтобы вернуть только информацию о неудачных операциях, используйте параметр запроса filter_path со значением items.*.error.

$params = [
    'body' => [
        [
            'update' => [
                '_id' => '5',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'my_field' => 'baz',
            ],
        ],
        [
            'update' => [
                '_id' => '6',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'my_field' => 'baz',
            ],
        ],
        [
            'update' => [
                '_id' => '7',
                '_index' => 'index1',
            ],
        ],
        [
            'doc' => [
                'my_field' => 'baz',
            ],
        ],
    ],
];
$response = $client->bulk($params);
resp = client.bulk(
    filter_path="items.*.error",
    operations=[
        {
            "update": {
                "_id": "5",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "my_field": "baz"
            }
        },
        {
            "update": {
                "_id": "6",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "my_field": "baz"
            }
        },
        {
            "update": {
                "_id": "7",
                "_index": "index1"
            }
        },
        {
            "doc": {
                "my_field": "baz"
            }
        }
    ],
)
print(resp)
response = client.bulk(
  filter_path: 'items.*.error',
  body: [
    {
      update: {
        _id: '5',
        _index: 'index1'
      }
    },
    {
      doc: {
        my_field: 'baz'
      }
    },
    {
      update: {
        _id: '6',
        _index: 'index1'
      }
    },
    {
      doc: {
        my_field: 'baz'
      }
    },
    {
      update: {
        _id: '7',
        _index: 'index1'
      }
    },
    {
      doc: {
        my_field: 'baz'
      }
    }
  ]
)
puts response
res, err := es.Bulk(
	strings.NewReader(`
{ "update": {"_id": "5", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "6", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "7", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
`),
	es.Bulk.WithFilterPath("items.*.error"),
)
fmt.Println(res, err)
const response = await client.bulk({
  filter_path: "items.*.error",
  operations: [
    {
      update: {
        _id: "5",
        _index: "index1",
      },
    },
    {
      doc: {
        my_field: "baz",
      },
    },
    {
      update: {
        _id: "6",
        _index: "index1",
      },
    },
    {
      doc: {
        my_field: "baz",
      },
    },
    {
      update: {
        _id: "7",
        _index: "index1",
      },
    },
    {
      doc: {
        my_field: "baz",
      },
    },
  ],
});
console.log(response);
POST /_bulk?filter_path=items.*.error
{ "update": {"_id": "5", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "6", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "7", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }

API возвращает следующий результат.

{
  "items": [
    {
      "update": {
        "error": {
          "type": "document_missing_exception",
          "reason": "[5]: document missing",
          "index_uuid": "aAsFqTI0Tc2W0LCWgPNrOA",
          "shard": "0",
          "index": "index1"
        }
      }
    },
    {
      "update": {
        "error": {
          "type": "document_missing_exception",
          "reason": "[6]: document missing",
          "index_uuid": "aAsFqTI0Tc2W0LCWgPNrOA",
          "shard": "0",
          "index": "index1"
        }
      }
    }
  ]
}
Пример с параметром динамических шаблонов

В приведенном ниже примере создается динамический шаблон, а затем выполняется массовый запрос, состоящий из запросов создания индекса с параметром dynamic_templates.

resp = client.indices.create(
    index="my-index",
    mappings={
        "dynamic_templates": [
            {
                "geo_point": {
                    "mapping": {
                        "type": "geo_point"
                    }
                }
            }
        ]
    },
)
print(resp)

resp1 = client.bulk(
    operations=[
        {
            "index": {
                "_index": "my_index",
                "_id": "1",
                "dynamic_templates": {
                    "work_location": "geo_point"
                }
            }
        },
        {
            "field": "value1",
            "work_location": "41.12,-71.34",
            "raw_location": "41.12,-71.34"
        },
        {
            "create": {
                "_index": "my_index",
                "_id": "2",
                "dynamic_templates": {
                    "home_location": "geo_point"
                }
            }
        },
        {
            "field": "value2",
            "home_location": "41.12,-71.34"
        }
    ],
)
print(resp1)
response = client.indices.create(
  index: 'my-index',
  body: {
    mappings: {
      dynamic_templates: [
        {
          geo_point: {
            mapping: {
              type: 'geo_point'
            }
          }
        }
      ]
    }
  }
)
puts response

response = client.bulk(
  body: [
    {
      index: {
        _index: 'my_index',
        _id: '1',
        dynamic_templates: {
          work_location: 'geo_point'
        }
      }
    },
    {
      field: 'value1',
      work_location: '41.12,-71.34',
      raw_location: '41.12,-71.34'
    },
    {
      create: {
        _index: 'my_index',
        _id: '2',
        dynamic_templates: {
          home_location: 'geo_point'
        }
      }
    },
    {
      field: 'value2',
      home_location: '41.12,-71.34'
    }
  ]
)
puts response
const response = await client.indices.create({
  index: "my-index",
  mappings: {
    dynamic_templates: [
      {
        geo_point: {
          mapping: {
            type: "geo_point",
          },
        },
      },
    ],
  },
});
console.log(response);

const response1 = await client.bulk({
  operations: [
    {
      index: {
        _index: "my_index",
        _id: "1",
        dynamic_templates: {
          work_location: "geo_point",
        },
      },
    },
    {
      field: "value1",
      work_location: "41.12,-71.34",
      raw_location: "41.12,-71.34",
    },
    {
      create: {
        _index: "my_index",
        _id: "2",
        dynamic_templates: {
          home_location: "geo_point",
        },
      },
    },
    {
      field: "value2",
      home_location: "41.12,-71.34",
    },
  ],
});
console.log(response1);
PUT my-index/
{
  "mappings": {
    "dynamic_templates": [
      {
        "geo_point": {
             "mapping": {
                "type" : "geo_point"
             }
        }
      }
    ]
  }
}

POST /_bulk
{ "index" : { "_index" : "my_index", "_id" : "1", "dynamic_templates": {"work_location": "geo_point"}} }
{ "field" : "value1", "work_location": "41.12,-71.34", "raw_location": "41.12,-71.34"}
{ "create" : { "_index" : "my_index", "_id" : "2", "dynamic_templates": {"home_location": "geo_point"}} }
{ "field" : "value2", "home_location": "41.12,-71.34"}

Массовый запрос создает два новых поля work_location и home_location типа geo_point в соответствии с параметром dynamic_templates; однако, поле raw_location создается с использованием правил динамической карты по умолчанию, как поле text в этом случае, поскольку оно предоставляется как строка в JSON-документе.

© 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-bulk.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API