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

В БД льются данные сразу в несколько потоков в разные индексы например в А и в Б. Поток А ищет данные в индексе Б и поток Б ищет в индексе А. Время пересоздания индекса стоит 1сек. Если в эту секунду добавить и попытаться найти данные, то БД их не найдет. Как быть в данном случае? Отключить время пересоздания? Но тогда диск будет постоянно занят и скорость добавления падает очень сильно

Что значит "пересоздание индекса"?

refresh_interval:1s

Да, такая конструкция будет крайне не оптимальной. А зачем вы ищите? Можно узнать больше о проблеме, которую вы пытаетесь этим решить?

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

Как происходит поиск? По id? Что происходить с записью планов, если она найдена?

Поиск идёт по ID. Если наши, то удаение

Почему тогда не поместить все в один индекс и использовать id как id документа? В этом случае ничего искать не надо, просто индексируете закупку с тем же id, и если план уже там - он просто автоматически удалится?

Не очень удобно.

  1. У закупки ID другой чем у плана. (это конечно можно сделать единым)
  2. При записи закупки необходимо найти предыдущую закупку с тем же ID но предыдущей версией и взять у неё дату её создания. Т. К. В закупках (это не наш формат) нет первой даты публикации. Её таким образом мы и получаем

Это можно сделать через Update API.

Проблему с refresh можно было бы решить заменой поиска на realtime get. Но это только уменьшит проблемы с секунд до миллисекунд, но не устранит ее полностью так как все равно получается состояние гонки:

  • поиск в A ничего не находит
  • поиск в B ничего не находит
  • записываем в B
  • записываем в A

Поскольку в Elasticsearch нет средств синхронизации и транзакций, и атомарные операции поддерживаются только на уровне одной записи, я не знаю, как это сделать без использования одной и той же записи для планов и закупок.

А update разве добавит запись в случае её отсутствия в индексе?

И я так понимаю real tine ещё больше увеличит нагрузку на диски, хотя диски и так нагружены на 100%

А update разве добавит запись в случае её отсутствия в индексе?

В режиме upsert - да

И я так понимаю real tine ещё больше увеличит нагрузку на диски, хотя диски и так нагружены на 100%

Вы можете увеличить refresh_interval и с отсутствием поиска нагрузка может уменьшиться. В режиме realtime elasticsearch использует список id записей, которые были проиндексированы после последнего рефреша. Этот список хранится в памяти и если запись, которую вы хотите прочитать, в этом списке, то elasticsearch выполняет автоматический рефреш.

Спасибо большое. Будем пробовать

Я так понимаю если использовать Script, то надо в этом скрипте перечислять все поля которые надо обновлять ... Что не есть хорошо, т.к. полей много и надо в скрипте знать структуру JSon. Если бы можно было бы передавать в Update еще и документ, в который и вставлять нужные данные из _source...

Тогда, можно прочитать старый документ через get, поменять его в вашем приложении и записать его снова используя метод описанный в optimistic concurrency control

Но если поставить refreshindex в более значение то get не найдёт же его))

Я вам вчера ссылку про realtime get прислал, Вы ее посмотрели?

By default, the get API is realtime, and is not affected by the refresh rate of the index (when data will become visible for search). If a document has been updated but is not yet refreshed, the get API will issue a refresh call in-place to make the document visible. This will also make other documents changed since the last refresh visible. In order to disable realtime GET, one can set the realtime parameter to false .

Да, точно. Спасибо. Попробую

Еще один вопрос, если использовать PrepareDelete, он так же будет работать как realtime ? Т.е. поищет ID в памяти и только потом уже будет искать в индексе? или сначала лучше найти с помощью realtime get?