В предыдущих статьях мы рассмотрели, как добавлять, заменять, обновлять и удалять отдельные документы. В этой лекции вы увидите, как выполнять эти операции пакетно. Для этого мы будем использовать API _bulk. Выполнение операций в пакетах очень эффективно, поскольку это ограничивает объем сетевых накладных расходов. Например, при выполнении 20 обновлений пакетная операция приведет к одному обходу сети вместо 20.
API _bulk ожидает строку с действием (т.е. создание, обновление или удаление), а также метаданные, за которыми следует необязательная строка источника действия. Исходный документ необязателен, поскольку он не нужен для удаления. Это можно повторять столько раз, сколько вы захотите. Важно отметить, что API _bulk использует новые строки (то есть \n) для вывода семантики данной строки, поэтому JSON не может быть отформатирован так, чтобы выглядеть красиво и охватывать несколько строк. Кроме того, последняя строка данных должна заканчиваться символом новой строки \n.
Давайте посмотрим пример и добавим два документа в наш индекс. Извините за форматирование, но запрос должен состоять всего из пяти строк: одна с HTTP-глаголом и URI запроса, и две для каждого продукта.
1 2 3 4 5 | curl -XPOST http://127.0.0.1:9200/ecommerce/product/_bulk -d ' {"index":{"_id":"1002"}} {"name":"Почему Elasticsearch - это круто","price":"50.00","description":"Эта книга - все об Elasticsearch!","status":"active","quantity":12,"categories":[{"name":"Software"}],"tags":["elasticsearch","programming"]} {"index":{"_id":"1003"}} {"name":"Peanuts","price":"3.00","description":"Арахис с солью.","status":"active","quantity":56,"categories":[{"name":"Food"}],"tags":["snacks"]}' |
Результат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | { "took": 339, "errors": false, "items": [ { "index": { "_index": "ecommerce", "_type": "product", "_id": "1002", "_version": 1, "_shards": { "total": 2, "successful": 1, "failed": 0 }, "status": 201 } }, { "index": { "_index": "ecommerce", "_type": "product", "_id": "1003", "_version": 1, "_shards": { "total": 2, "successful": 1, "failed": 0 }, "status": 201 } } ] } |
Как видно из результатов, оба наших действия были успешными. Откройте Kibana и выполните поиск "Elasticsearch", чтобы убедиться, что документы были добавлены.
Далее попробуем сделать массовый запрос с более чем одним видом действия. Я удалю продукт с идентификатором 1 и обновлю один из продуктов, которые я добавил незадолго до этого. Я обновлю количество книги, которую я добавил, с 12 до 11, чтобы имитировать продажу одного экземпляра.
1 2 3 4 | curl -XPOST http://127.0.0.1:9200/ecommerce/product/_bulk -d ' { "delete" : { "_id" : "1" } } { "update" : { "_id" : "1002" } } } { "doc" : { "quantity" : 11 } }' |
Еще раз проверим, что все работает.
1 | curl -xGET http://127.0.0.1:9200/ecommerce/product/1 |
Документ с идентификатором 1 больше не существует в индексе электронной коммерции, что означает, что он был успешно удален. Далее перейдите в Kibana и выполните поиск по слову "Elasticsearch", чтобы найти книгу, которую мы добавили, и убедитесь, что ее количество теперь равно 11.
Перед завершением этой статьи я хочу отметить несколько моментов. В строках, где указывается выполняемое действие, можно также указать название индекса и тип документа, который нужно использовать. В нашем примере эти данные присутствовали в URL, но если мы добавим их в качестве свойств _index и _type соответственно, нам не придется указывать эту информацию в URL. Это удобно, если массовый запрос затрагивает несколько индексов и/или типов. Если, однако, индекс/тип указаны, они будут использоваться по умолчанию для массовых элементов, которые не указывают их явно.
При отправке массовых запросов индекс и тип не являются обязательными в URL. Если информация доступна в рамках действий, вы можете выполнить любое из следующих действий.
1 2 3 | POST /ecommerce/product/_bulk POST /ecommerce/_bulk POST /_bulk |
В этом примере я просто опущу индекс и тип и укажу их в действии. Мы просто смоделируем, что мы продали еще один экземпляр книги.
1 2 3 | curl -XPOST http://127.0.0.1:9200/_bulk -d ' { "update" : { "_id" : "1002", "_index" : "ecommerce", "_type" : "product" } } { "doc" : {"quantity" : 10 } }' |
Зайдя в Kibana и обновив поиск, вы увидите, что мы обновили документ так же, как и в предыдущем случае.
Еще один момент, о котором стоит упомянуть, заключается в том, что все действия в массовом запросе выполняются последовательно и по порядку. Если одно действие по какой-либо причине не будет выполнено, остальные действия будут обработаны и останутся незатронутыми. Ответ на массовый запрос включает статус для каждого действия, которое было выполнено в том же порядке, в котором они были запрошены. Это полезно для проверки того, удалось или не удалось выполнить определенное действие.
Это все, что касается массовых запросов. Их следует использовать всякий раз, когда вам нужно одновременно изменить достаточно большое количество документов, чтобы повысить производительность.