Elastic Search Scroll API异步执行

时间:2019-01-29 03:40:55

标签: api elasticsearch asynchronous search scroll

我正在运行一个弹性搜索集群5.6版本,每天索引大小为70Gb。在一天结束时,我们要求对过去7天的每个小时进行汇总。我们正在使用High Rest客户端的Java版本,并考虑到每个查询返回的文档数量对于滚动结果至关重要。

为了利用我们拥有的CPU并减少读取时间,我们曾在考虑使用Search Scroll Asynchronous版本,但我们缺少一些示例,至少缺少其中的逻辑。

我们已经检查了与弹性有关的文档,但是含糊不清:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/5.6/java-rest-high-search-scroll.html#java-rest-high-search-scroll-async

我们还在弹性讨论论坛中以他们所说的方式提问,但似乎没人能回答:

https://discuss.elastic.co/t/no-code-for-example-of-using-scrollasync-with-the-java-high-level-rest-client/165126

任何对此的帮助将不胜感激,可以肯定的是,我不是唯一拥有此要求的人。

2 个答案:

答案 0 :(得分:0)

  

最近7天每小时的摘要

听起来您想对数据运行一些汇总,而不要获取原始文档。可能在第一级上是日期直方图,以便每隔1小时进行一次汇总。在该日期直方图中,您需要一个内部aggs来运行您的汇总-根据所需的汇总来选择指标/存储桶。

从Elasticsearch v6.1开始,您可以使用Composite Aggregation以便通过分页获取所有结果存储桶。从我链接的文档中:

  

复合聚合可用于从多级聚合有效地对所有存储桶进行分页。这种聚合提供了一种方式来流传输特定聚合的所有存储桶,类似于滚动对文档所做的操作。

不幸的是,此选项在v6.1之前不存在,因此您要么需要升级ES才能使用它,要么找到另一种方式(例如中断多个查询)一起满足7天的需求。

答案 1 :(得分:0)

下面是示例代码:

    public class App {
    public static void main(String[] args) throws IOException, InterruptedException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(HttpHost.create("http://localhost:9200")));

        client.indices().delete(new DeleteIndexRequest("test"), RequestOptions.DEFAULT);
        for (int i = 0; i < 100; i++) {
            client.index(new IndexRequest("test", "_doc").source("foo", "bar"), RequestOptions.DEFAULT);
        }
        client.indices().refresh(new RefreshRequest("test"), RequestOptions.DEFAULT);

        SearchRequest searchRequest = new SearchRequest("test").scroll(TimeValue.timeValueSeconds(30L));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        String scrollId = searchResponse.getScrollId();

        System.out.println("response = " + searchResponse);

        SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId)
                .scroll(TimeValue.timeValueSeconds(30));


        //I was missing to wait for the results
        final CountDownLatch countDownLatch = new CountDownLatch(1);

        client.scrollAsync(scrollRequest, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {
            public void onResponse(SearchResponse searchResponse) {
                System.out.println("response async = " + searchResponse);
            }

            public void onFailure(Exception e) {

            }
        });

        //Here we wait
        countDownLatch.await();

        //Clear the scroll if we finish before the time to keep it alive. Otherwise it will be clear when the time is reached.    
        ClearScrollRequest request = new ClearScrollRequest()
        request.addScrollId(scrollId);

        client.clearScrollAsync(request, new ActionListener<ClearScrollResponse>(){
           @Override
           public void onResponse(ClearScrollResponse clearScrollResponse) {
           }

           @Override
           public void onFailure(Exception e) {
           }
         });

        client.close();           
       }
    }

感谢David Pilato elastic discussion