Раздел 40 · Elasticsearch и ELK

Индексация документов: PUT, POST и bulk

junior~10 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Рестораны «Гонца» каждый день добавляют блюда, меняют цены и убирают то, что закончилось. Все эти изменения надо донести до Elasticsearch. Запись документа в индекс называют индексацией. Разберём, какими запросами это делается и почему записанное блюдо иногда не находится сразу.

Запись с известным id и без

Есть два способа записать документ:

  • PUT /dishes/_doc/new1 записывает документ с _id new1. Если такого нет, он создаётся (ответ 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 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.