我的单元/集成测试包括搜索功能的测试。
我的想法是在每次测试前都有空搜索索引。所以,我试图删除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 :(得分: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();
将新数据放入索引后。
答案 1 :(得分: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
我在测试中这样做,从来没有遇到过问题。
答案 2 :(得分:5)
通过以下方式删除所有项目:
client.prepareDeleteByQuery(indexName).
setQuery(QueryBuilders.matchAllQuery()).
setTypes(indexType).
execute().actionGet();
刷新索引以查看更改(仅在单元测试中需要)
答案 3 :(得分:0)
我的想法是在每次测试前都有空的搜索索引
因此,在测试开始时创建一个新索引,不要重复使用旧索引。那你就保证空了。在测试的拆解中,您可以删除测试索引。
有没有办法提交最后的更改,或者在写入所有数据之前进行锁定?
不,ElasticSearch没有交易或锁定。
如果您不想每次都创建新索引,那么尝试添加一个循环来检查索引是否为空,然后等待并再次尝试,直到它为止。