java使用ElasticSearch的scroll查詢,高效的解決es查詢數(shù)量的限制。
一、為什么要使用ES的scroll
(1)首先我們要明白es的查詢機制:ES的搜索是分2個階段進行的,即Query階段和Fetch階段。
-
Query階段比較輕量級,通過查詢倒排索引,獲取滿足查詢結(jié)果的文檔ID列表。
-
Fetch階段比較重,需要將每個分片的查詢結(jié)果取回,在協(xié)調(diào)結(jié)點進行全局排序。 通過From+size這種方式分批獲取數(shù)據(jù)的時候,隨著from加大,需要全局排序并丟棄的結(jié)果數(shù)量隨之上升,性能越來越差。
(2)es在進行普通的查詢時,默認只給查詢出來十條數(shù)據(jù)。
? 通過設置size的值可以使查詢結(jié)果從10增大到1000條數(shù)據(jù),當超出1000條數(shù)據(jù)的時候就會只顯示出來1000條數(shù)據(jù)。
? 為了解決上面的問題可以采用一種效率比較低的方法,在創(chuàng)建索引的時候添加如下配置
-
"settings":{ "index":{ "max_result_window": 在這里填入你需要的大小 } }
(3)如果進行高效的查詢呢?那就需要使scroll滾動查詢了。
? Scroll查詢,先做輕量級的Query階段以后,免去了繁重的全局排序過程。 它只是將查詢結(jié)果集,也就是doc_id列表保留在一個上下文里, 之后每次分批取回的時候,只需根據(jù)設置的size,在每個分片內(nèi)部按照一定順序(默認doc_id續(xù)), 取回size數(shù)量大小的數(shù)據(jù)即可。
二、如何使用scroll
(1)首先引入elasticsearch的坐標文章來源:http://www.zghlxwxcb.cn/news/detail-436834.html
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
(2)編寫如下代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-436834.html
/**
* 使用es的scroll方法來滾動查詢es的數(shù)據(jù),可以有效的解決大數(shù)據(jù)容量讀取的限制
* @param index es的索引名稱
* @param host es的主機ip號
* @param port es的端口號
* @param beginDate 構造查詢條件需要的條件之一 (可以根據(jù)自己需求定義es的查詢條件)
* @param endDate 構造查詢條件需要的條件之一 (可以根據(jù)自己需求定義es的查詢條件)
*/
public void scrollDemo(String index,String host,int port,String beginDate,String endDate) throws ParseException {
RestHighLevelClient restHighLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost(host,port,"http")));
//構造查詢條件
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
//設置查詢超時時間
Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L));
builder.query(QueryBuilders.rangeQuery("datetime").gte(beginDate).lte(endDate));
//設置最多一次能夠取出1000筆數(shù)據(jù),從第1001筆數(shù)據(jù)開始,將開啟滾動查詢
//PS:滾動查詢也屬于這一次查詢,只不過因為一次查不完,分多次查
builder.size(1000);
searchRequest.source(builder);
//將滾動放入
searchRequest.scroll(scroll);
SearchResponse searchResponse = null;
try {
searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
System.out.println("查詢索引庫失敗");
}
SearchHits hits= searchResponse.getHits();
SearchHit[] hit= hits.getHits();
/**
*在這個位置已經(jīng)讀到了前一千條數(shù)據(jù),可以在這先對這一千數(shù)據(jù)進行處理。下面滾動查詢剩下的數(shù)據(jù)
*/
//記錄要滾動的ID
String scrollId = searchResponse.getScrollId();
//滾動查詢部分,將從第1001筆數(shù)據(jù)開始取
SearchHit[] hitsScroll = hits.getHits();
while (hitsScroll != null && hitsScroll.length > 0 ) {
//構造滾動查詢條件
SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
searchScrollRequest.scroll(scroll);
try {
//響應必須是上面的響應對象,需要對上一層進行覆蓋
searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
System.out.println("滾動查詢失敗");
}
scrollId = searchResponse.getScrollId();
hits = searchResponse.getHits();
hitsScroll = hits.getHits();
/**
*在這個位置可以對滾動查詢到的從1001條數(shù)據(jù)開始的數(shù)據(jù)進行處理。
*/
}
//清除滾動,否則影響下次查詢
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
ClearScrollResponse clearScrollResponse = null;
try {
clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest,RequestOptions.DEFAULT);
} catch (IOException e) {
System.out.println("滾動查詢刪除失敗");
}
//清除滾動是否成功
boolean succeeded = clearScrollResponse.isSucceeded();
}
到了這里,關于java使用ElasticSearch的scroll查詢,高效的解決es查詢數(shù)量的限制。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!