【问题描述】:

我有一个可以从 Elasticsearch 导出一些报告数据的 rest 应用程序。使用 Java API 很容易做到:

SearchResponse response = getClient()
            .prepareSearch("my_index_name")
            .setQuery(QueryBuilders.someQuery())
            .addAggregation(AggregationBuilders.someAggregation())
            .get();

问题始于大反应。使用此代码 sn-p,读取响应以在内存中构建 SearchResponse 对象。在我的情况下,响应不适合记忆

分页无济于事,因为我们经常需要返回完整的数据和聚合do not support paging yet

我知道我可以使用 Elasticsearch REST API 将响应读取为流,但是手动构建请求很麻烦。我真的很想要这样的东西:

// my dream API
InputStream response = getClient()
            .prepareSearch("my_index_name")
            .setQuery(QueryBuilders.someQuery())
            .addAggregation(AggregationBuilders.someAggregation())
            .getStream();

那么,Elasticsearch Java API 可以流式传输 SearchResponse 吗?

【问题讨论】:

    标签: java performance elasticsearch stream inputstream


    【解答1】:

    proposal for streaming results 确实存在,但到目前为止它似乎还没有恢复活力并且已经关闭(暂时)。

    有一种方法可以使用 XContentBuilder 来实现,但这仍然需要在发送之前将整个响应保存在内存中。

    这可能不是您想要的,但这是我所知道的最能满足您需求的东西。值得一试。

    【问题讨论】:

      【解答2】:

      我相信没有办法从 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
      

      【问题讨论】: