Документ не удаляется, если запрос на удаление был отправлен сразу после запроса на вставку

У меня есть служба, которая индексирует документы. Сервис получает два следующих запроса — первый на вставку документа и второй на его удаление. Когда между ними есть какое-то время, он работает нормально, но когда они отправляются друг за другом, документ не удаляется. Ответ, который я получаю от Nest, выглядит успешным.

Моя функция довольно длинная, поэтому я буду писать только вставку и удаление внутри. Если потребуется дополнительная информация, я добавлю ее (например, в случае вставки также удаляет ее из всех других доступных индексов и при необходимости вставляет некоторое сопоставление).

Код вставки:

IBulkResponse res = await _client.IndexManyAsync(entities, index, type);

Удалить код:

var termFilter = new List<Func<QueryContainerDescriptor<JObject>, QueryContainer>>
        {
            c => c.Terms(t => t.Field(ID_FIELD).Terms(ids))
        };

        await _client.DeleteByQueryAsync<JObject>(indices, types, d => d.Query(q => q.Bool(b => b.Must(termFilter))));

Например, этот интеграционный тест не работает:

var indices = new { "some_index_1", "some_index_2" };
var entity = new Entity {  Action = ReplicationAction.INSERT, ... };
await elasticDal.Insert(new List { entity }, "some_index_1", "666", indices);
entity.Action = ReplicationAction.DELETE;
await elasticDal.Insert(new List { entity }, "some_index_1", "666", indices);

Версии: ElasticSearch 2.3.5, .Net 4.6, Nest 2.4.6.


person Mei    schedule 30.08.2017    source источник
comment
Этот вопрос не имеет принятого ответа. Как вы решили эту проблему?   -  person Avi    schedule 24.07.2021


Ответы (1)


Когда вы вставляете любой документ, происходят следующие шаги:

  1. Документ добавляется в буфер в памяти и добавляется в транслог.
  2. Обновить Документы в буфере в памяти записываются в новый сегмент без fsync.

    а. Сегмент открывается, чтобы сделать его видимым для поиска.

    б. Буфер в памяти очищается.

  3. Сегмент открывается, чтобы сделать его видимым для поиска.

  4. Время от времени — например, когда транслог становится слишком большим — индекс сбрасывается; создается новый транслог и выполняется полная фиксация:

    а. Любые документы в буфере памяти записываются в новый сегмент.

    б. Буфер очищается.

    в. Точка фиксации записывается на диск.

    д. Кэш файловой системы очищается с помощью fsync.

    е. Старый транслог удален.

Elasticsearch не удаляет документ, он помечает документ как удаленный документ, и при объединении сегментов индекса ES оставляет удаленный документ, если он находится в памяти.

Итак, я предполагаю, что после удаления вам не хватает API обновления. Если ваш DELETE API используется не так часто, вы можете обновить ES после вызова DELETE API, вызвав REFRESH API.

Если вы хотите узнать больше о том, как происходит индексация изображения, вы можете перейти по этой ссылке (https://www.elastic.co/guide/en/elasticsearch/guide/current/translog.html)

person Nikunj Aggarwal    schedule 30.08.2017
comment
удаления довольно часты в этом случае. и есть другие случаи, когда мне нужно удалить много документов одновременно. Должен ли я по-прежнему использовать API обновления? если нет, что еще я могу сделать? - person Mei; 30.08.2017
comment
я только что попытался использовать API-интерфейс обновления ( await _client.RefreshAsync (новый RefreshRequest (индексы)) ), но это не помогает - person Mei; 30.08.2017
comment
ES обновляет каждую секунду. Так что можете поставить сон, скажем, на одну-две секунды, а если ваша частота меньше одного документа в секунду, вы можете поставить обновление. Но мое предложение заключается в том, чтобы поспать одну секунду. - person Nikunj Aggarwal; 30.08.2017
comment
Каким было окончательное решение этой проблемы? - person Avi; 24.07.2021