[ElasticSearch]ES操作之游標查詢Scroll Search


一.  什么是游標查詢(Scroll)

  顧名思義,相當於用一把游標標記查詢的位置.

 

二.  為什么要使用游標查詢

  在默認情況下,ES查詢每次返回的數量最多只有1W條,且只能是前1W條.

  這意味着,在不修改配置的情況下,想通過分頁的方式(如下)拿到1W條之后的數據是做不到的

GET /索引/類型/_search
{
  "size": 10000, 
  "from": 5000, 
  "query": {
    ...   
  }, 
  "aggs": {
    ...  
  }
}

所以自然就有了游標查詢.

 

三.  如何使用游標查詢

DSL的用法:

GET 索引/類型/_search?scroll=1m
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

1m表示:過期時間1分鍾

 

查詢結果的第一行會有:

  "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBAAAAAAABO-dFmRFSU9NM1VNU2JxNG9UUlNnSmpXMVEAAAAAAL7J_hYxT0dJOVJVMVFxU2I0N2xCR2IyVzJnAAAAAAC-    SmQWWk1aN0sxUmRSQmFNS3EwVFh0R0luUQAAAAAAvkplFlpNWjdLMVJkUkJhTUtxMFRYdEdJblE=",

這個_scroll_id就相當於書簽,之后的查詢帶着這個書簽,就能根據size不斷拿到之后的數據,但是前提是在過期時間之內

 

之后的查詢DSL:

GET _search/scroll
{
  "scroll":"1m",
  "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBAAAAAAABPP1FmRFSU9NM1VNU2JxNG9UUlNnSmpXMVEAAAAAAL7OTxYxT0dJOVJVMVFxU2I0N2xCR2IyVzJnAAAAAAC-j70WVVlOZkxQRzJRLXlMRlVMbEQtalBfUQAAAAAAyWm-Fk9HdGx1b3VsUXRLZHV4c1E1OExja0E="
}

將獲取的scroll_id作為條件繼續查詢即可,這里不需要再指定索引和類型,因為scroll_id的唯一性.

在過期時間內,之后的查詢的scroll_id是不變的.

 

四.  基於java代碼:

     RestClient lowClient = RestClient.builder(new HttpHost("主機",端口))
                .setMaxRetryTimeoutMillis(300000).build();
        RestHighLevelClient client = new RestHighLevelClient(lowClient);
        SearchRequest request = new SearchRequest("索引").types("類型");
     //這里一次查1W條 SearchSourceBuilder sourceBuilder
= new SearchSourceBuilder().size(10000); request.source(builder).searchType(SearchType.DEFAULT); //這句代碼就是設置游標查詢和過期時間
     request.scroll(TimeValue.timeValueMinutes(
5)); SearchResponse response = client.search(request);      // search     SearchResponse response = client.search(request);     //定義游標
    String scrollId
= null;     if (response != null && response.getHits().getHits().length > 0) {    for (SearchHit hit : response.getHits().getHits()) {   //TODO    }
     //拿到游標    scrollId
= response.getScrollId();     }     //一直查詢,直到沒有游標返回(查詢到底了)     while (true){    if(scrollId == null){   break;    }   SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId).scroll(TimeValue.timeValueMinutes(5));;   response = client.searchScroll(searchScrollRequest);   if (response != null && response.getHits().getHits().length > 0) {   for (SearchHit hit : response.getHits().getHits()) { //TODO   }   scrollId = response.getScrollId();   }else {   break;   }     }

到這里,游標查詢的基本操作就OK了.有一點需要注意:

  游標的方式,相當於mysql中生成快照的方式,所以如果在游標查詢期間有增刪改操作,是獲取不到最新的數據的.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM