Нужна поддержка внешней версии в операции обновления OpenSearch

Я использую OpenSearch для индексации документов JSON и делаю их доступными для поиска. Все документы имеют поле отметки времени обновления в формате EPOCH. Проблема в том, что я могу получить запрос на обновление, в котором тело документа содержит более раннее время обновления. Мое приложение должно пропустить обновление, если текущее время обновления документа старше, чем поле времени обновления в существующем документе, хранящемся в OpenSearch.

Чтобы выполнить требование, я добавил внешнюю версию в HTTP-запрос /test_index/_update/123?version=1674576432910&version_type=external.

Но я получаю ошибку

Ошибка проверки: 1: внутреннее управление версиями нельзя использовать для управления оптимистичным параллелизмом. Вместо этого используйте if_seq_no и if_primary_term.

Я читал о полях if_seq_no и if_primary_term. Они не могут быть использованы для решения моей проблемы. Кто-нибудь еще сталкивался с этой проблемой и решил ее? Поделись, пожалуйста. Или, если кто-нибудь знает о каком-либо плагине, который я могу установить для поддержки этого, пожалуйста, поделитесь.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны использовать параметры «if_seq_no» и «if_primary_term» для управления оптимистичным параллелизмом.

Чтобы решить вашу проблему, вы можете сначала получить существующий документ из OpenSearch, используя идентификатор документа, и проверить поле отметки времени обновления. Если существующая метка времени новее, чем в запросе на обновление, обновление можно пропустить. В противном случае вы можете включить параметры «if_seq_no» и «if_primary_term» в свой запрос на обновление вместе с обновленным документом. Параметр «if_seq_no» должен быть установлен на порядковый номер существующего документа, а параметр «if_primary_term» должен быть установлен на основной термин существующего документа.

Для этого можно использовать Update API... или механизм Optimistic Concurrency Control (OCC), основанный на сочетании полей _seq_no и _primary_term.

Спасибо за ответ, я так и думал. Есть одна проблема. Пример: я добавил if_seq_no и if_primary_term в запрос на обновление. Прежде чем произойдет фактическое обновление, я получил еще один запрос на обновление для того же документа с более высокой меткой времени обновления. Второе обновление также должно произойти. Но seq_no изменится из-за первого обновления, и из-за этого второе обновление не удастся. У меня нет контроля, и могут поступать одновременные вызовы обновлений, и мы можем пропустить действительное обновление.

muthuk 25.01.2023 11:10
Ответ принят как подходящий

К сожалению, ни OpenSearch, ни ElasticSearch не поддерживают внешнюю версию в запросе на обновление. И я не думаю, что эта функция будет добавлена ​​в ближайшем будущем. Вы можете решить свою конкретную проблему с помощью сценариев. OpenSearch поддерживает несколько языков сценариев, включая сценарий Painless. Вы можете написать скрипт, который будет сравнивать конкретное поле (в вашем случае отметку времени обновления). И если условие истинно, оно продолжит и обновит поля новыми значениями.

{
    "script": {
        "lang": "painless",
        "source": "if (params.updateTimestamp > ctx._source.updateTimestamp) {for (entry in params.entrySet()) {ctx._source[entry.getKey()] = entry.getValue();}}"
    }
}

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

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

Другие вопросы по теме