如何删除ElasticSearch索引?

28

我的单元/集成测试包括对搜索功能的测试。

我的想法是在每次测试之前都有一个空的搜索索引。因此,我正在尝试在setup方法中删除索引中的所有元素(这是Groovy代码):

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()看起来并不是很好的解决方案。

是否有任何方法可以提交最近的更改,或者在所有数据被写入之前进行锁定?


不需要调用flush,只需调用refresh API以确保您可以在最近索引的数据上进行搜索。 - kimchy
4个回答

33

找到解决方案:

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();

将新数据放入索引后。


谢谢。您使用了哪个库并且如何建立连接? - Nagappa L M

30

首先,您无需通过删除每个文档ID来清除所有数据。您可以通过使用delete by query匹配所有文档来仅删除所有数据。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

我在我的测试中这样做,从未遇到问题。


8
无需清空缓存,只需调用刷新API以确保您搜索最新数据。 - kimchy
谢谢kimchy,已在回答中修复! - johno
链接已不再可用。 - vdolez

6
  1. it is not the async call (you can add a listener and avoid actionGet to get the async call)
  2. delete all items via:

    client.prepareDeleteByQuery(indexName).
                setQuery(QueryBuilders.matchAllQuery()).
                setTypes(indexType).
                execute().actionGet();
    
  3. refresh your index to see the changes (only required in unit tests)


2
我的测试表明,删除所有项目比重新创建索引更快... - Karussell

0
我的想法是在每次测试之前都有一个空的搜索索引。
因此,在测试开始时创建一个新索引,不要重复使用旧索引。这样就保证了一个空索引。在测试的拆卸中,您可以删除测试索引。
没有办法提交最后的更改,或者进行锁定直到所有数据都被写入。
ElasticSearch没有事务或锁定功能。
如果您不想每次都创建新索引,那么尝试添加一个循环来检查索引是否为空,然后等待并重试,直到它为空为止。

是的,这就是我要找的。我该如何创建一个新索引? - Igor Artamonov
@splix:http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html - skaffman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接