2011-11-05 98 views
27

我的单元/集成测试包括对搜索功能的测试。如何清除ElasticSearch索引?

我的想法是在每次测试前都有空搜索索引。所以,我想,以消除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()放在可能看起来不太好的解决方案。

它有什么办法提交最后修改,或者做出,直到所有数据将被写入?

+0

无需调用flush,只需调用API刷新,以确保您可以在索引的最新数据搜索。 – kimchy

回答

34

实测溶液:

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

把新数据索引之后。

+0

谢谢你..这图书馆,你是怎么连接? –

0

我的想法是让每个测试之前空搜索索引

所以在测试开始创建新的索引,不要重复使用旧的。那么你保证一个空的。在测试的拆解中,您可以删除测试索引。

有没有办法提交上次更改或锁定,直到所有数据都将被写入?

不,ElasticSearch没有事务或锁定。

如果你不想每次都创建新的索引,那么尝试添加一个循环来检查索引是否为空,然后等待并再次尝试,直到它为止。

+0

是的,这就是我要找的。我如何创建一个新的索引? –

+0

@splix:http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html – skaffman

5
  1. 它不是异步调用(你可以添加一个监听器,避免actionGet得到异步调用)
  2. 通过删除所有项目:

    client.prepareDeleteByQuery(indexName). 
          setQuery(QueryBuilders.matchAllQuery()). 
          setTypes(indexType). 
          execute().actionGet(); 
    
  3. 刷新指数看变化(仅在单元测试中需要)

+2

我的测试表明,删除所有项目更快然后重新创建索引... – Karussell

29

首先你不必通过发行上的每个文档ID的删除清除所有数据。您可以通过查询匹配所有文档来删除所有数据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

+0

感谢kimchy,固定答案! – johno

+0

链接不再可用。 – vdolez