Я использую 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. Они не могут быть использованы для решения моей проблемы. Кто-нибудь еще сталкивался с этой проблемой и решил ее? Поделись, пожалуйста. Или, если кто-нибудь знает о каком-либо плагине, который я могу установить для поддержки этого, пожалуйста, поделитесь.
Вы должны использовать параметры «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.
К сожалению, ни 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 в этой статье.
Спасибо за ответ, я так и думал. Есть одна проблема. Пример: я добавил if_seq_no и if_primary_term в запрос на обновление. Прежде чем произойдет фактическое обновление, я получил еще один запрос на обновление для того же документа с более высокой меткой времени обновления. Второе обновление также должно произойти. Но seq_no изменится из-за первого обновления, и из-за этого второе обновление не удастся. У меня нет контроля, и могут поступать одновременные вызовы обновлений, и мы можем пропустить действительное обновление.