Рестораны «Гонца» каждый день добавляют блюда, меняют цены и убирают то, что закончилось. Все эти изменения надо донести до Elasticsearch. Запись документа в индекс называют индексацией. Разберём, какими запросами это делается и почему записанное блюдо иногда не находится сразу.
Запись с известным id и без
Есть два способа записать документ:
PUT /dishes/_doc/new1записывает документ с_idnew1. Если такого нет, он создаётся (ответ201 Created), если есть, заменяется целиком (200 OK,"result": "updated");POST /dishes/_docзаписывает документ, а_idпридумывает Elasticsearch: случайную строку вродеKMhy8dxsMOxGHf2twzQU.
Свой _id удобен, когда у объекта уже есть номер в основной базе: блюдо d634 в PostgreSQL и в Elasticsearch под одним номером. Тогда повторная запись того же блюда просто заменит старую версию, а не создаст дубль. Автоматический _id подходит для событий, которые не меняются, например для логов.
Если дубль недопустим, есть PUT /dishes/_create/new1: он создаёт документ, только если такого _id ещё нет, иначе отвечает 409 Conflict.
Версии
У каждого документа есть _version: при каждом изменении она растёт на единицу. А _seq_no это сквозной номер операции в шарде. По ним Elasticsearch защищает от одновременной записи: можно сказать «обнови, только если документ не менялся с тех пор, как я его прочитал» параметрами if_seq_no и if_primary_term. Это оптимистичная блокировка, как в базах данных.
Обновление части документа
PUT заменяет документ целиком: если передать только цену, исчезнут название и всё остальное. Чтобы поменять одно поле, есть _update:
POST /dishes/_update/new1
{ "doc": { "price_rub": 340 } }
Внутри это всё равно полная перезапись: Elasticsearch читает документ, меняет поле и записывает новую версию, а старую помечает удалённой. Документы в Lucene не правятся на месте, это мы обсуждали в уроке про инвертированный индекс.
Удаление: DELETE /dishes/_doc/new1.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.