我有一个rest应用程序,可以从Elasticsearch导出一些报告数据。使用Java API很容易做到:
SearchResponse response = getClient()
.prepareSearch("my_index_name")
.setQuery(QueryBuilders.someQuery())
.addAggregation(AggregationBuilders.someAggregation())
.get();
问题始于巨大的反响。使用这个代码片段,读取响应以在内存中构建SearchResponse
对象。在我的情况下,的响应不适合内存。
分页没有帮助,因为我们经常需要返回完整的数据,而聚合还不支持分页。
我知道我可以使用ElasticsearchRESTneneneba API将响应读取为流,但手动构建请求很麻烦。我真的想要这样的东西:
// my dream API
InputStream response = getClient()
.prepareSearch("my_index_name")
.setQuery(QueryBuilders.someQuery())
.addAggregation(AggregationBuilders.someAggregation())
.getStream();
那么,Elasticsearch Java API是否可以流式传输SearchResponse
?
确实存在一个流媒体结果的提案,但到目前为止,它似乎还没有启动,(目前)已经关闭。
有一种方法可以用XContentBuilder
来实现,但这仍然需要在发送之前将整个响应保存在内存中。
这可能不是你想要的,但这是我所知道的最接近的东西,可以满足你的需求。值得一试。
我认为没有办法从Java API获得InputStream
(但我可能错了)。我还认为在Jest(一种基于REST的Elasticsearch Java API)中没有办法直接获得InputStream
。
您提到,自己创建到_search
端点的搜索请求很麻烦:如果您指的是构建实际的json查询,我只想指出,一旦您有了SearchSourceBuilder
,您就可以在它上调用toString()
,以获得查询的完整工作json表示。
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(this.getQuery())
.from(this.getFrom())
.size(this.getSize())
.fetchSource(this.getSource(), null);
this.getSort().forEach(sourceBuilder::sort);
sourceBuilder.toString() // the json representation