Подтвердить что ты не робот

Как удалить индекс ElasticSearch?

Мои тесты / включают тесты для функции поиска.

Моя идея - иметь пустой индекс поиска перед каждым тестом. Итак, я пытаюсь удалить все элементы в индексе по методу setup (это Groovy code):

Client client = searchConnection.client

SearchResponse response = client.prepareSearch("item")
    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
    .setQuery(termQuery('name', 'test')) //tried also matchAllQuery()
    .setFrom(0).setSize(100).setExplain(false).execute().actionGet()

List<String> ids = response.hits.hits.collect {
    return it.id
}
client.close()

client = searchConnection.client

ids.each {
    DeleteResponse delete = client.prepareDelete("item", "item", it)
        .setOperationThreaded(false)
        .execute().actionGet()
}

client.close()

Кажется, что он обрабатывает все удаления асинхронно, поэтому я добавил Thread.sleep(5000) после него. Как вы видите, я пытаюсь открыть/закрыть соединение несколько раз - это не помогает.

Проблема, которая иногда требует большего времени, иногда требуется больше 5 секунд для удаления, иногда она не может найти только добавленные данные (из предыдущего теста) и т.д. и т.д. И самое раздражающее, что интеграционные тесты становятся неустойчивыми. Помещение Thread.sleep() везде, где это возможно, выглядит не очень хорошим решением.

Он может каким-либо образом зафиксировать последними изменениями или сделать блокировку до тех пор, пока все данные не будут записаны?

4b9b3361

Ответ 1

Найдено решение:

IndicesAdminClient adminClient = searchConnection.client.admin().indices();
String indexName = "location";
DeleteIndexResponse delete = adminClient.delete(new DeleteIndexRequest(indexName)).actionGet()
if (!delete.isAcknowledged()) {
    log.error("Index {} wasn't deleted", indexName);
}

и

client.admin().indices().flush(new FlushRequest('location')).actionGet();

после ввода новых данных в индекс.

Ответ 2

Прежде всего, вам не нужно очищать все данные, удаляя их по каждому идентификатору doc. Вы можете просто удалить все данные с удалением по запросу, соответствующему всем документам http://www.elasticsearch.org/guide/reference/api/delete-by-query.html После этого я также не рекомендую это, потому что это не рекомендуется часто делать это в больших коллекциях документов (см. документы).

То, что вы действительно хотите сделать, это удалить весь индекс (быстро) http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index.html, воссоздать его, поместить в данные и это важно обновить индекс, чтобы "зафиксировать" изменения и сделать их видимыми. http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh.html

Я делаю это в своих тестах и ​​никогда не испытывал проблем.

Ответ 3

  • это не асинхронный вызов (вы можете добавить слушателя и избежать actionGet, чтобы получить асинхронный вызов)
  • удалить все элементы с помощью:

    client.prepareDeleteByQuery(indexName).
                setQuery(QueryBuilders.matchAllQuery()).
                setTypes(indexType).
                execute().actionGet();
    
  • обновите свой индекс, чтобы увидеть изменения (требуется только в модульных тестах)

Ответ 4

Моя идея - иметь пустой индекс поиска перед каждым тестом

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

Есть ли способ зафиксировать последние изменения или сделать блокировку до тех пор, пока все данные не будут записаны?

Нет, ElasticSearch не имеет транзакций или блокировки.

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