一. 為什么用深度分頁scroll查詢
分頁可以用terms查詢的from to來實現;但是from to二者之和大於一萬后就效率低下. 原因是
es查詢的方式:
- 將用戶指定的關鍵字進行分詞,
- 將詞匯去分詞庫中去檢索. 得到多個文檔的id
- 去各個分片中去拉取指定數據; 這步最慢
- 將數據根據匹配度score排序; 耗時長
- 將查詢的數據舍棄一部分: 如from5to10, 就把不是5-10條的數據舍棄
- 返回結果
scroll查詢的方式:
- 將用戶指定的關鍵字進行分詞,
- 將詞匯去分詞庫中去檢索. 得到多個文檔的id,
- 將id存在一個es的上下文中
- 根據size鍵es中檢索指定的數據, 拿到數據的文檔id, 會從上下文中移出,
- 如果需要下一頁數據, 直接到es的上下文中找到后續的內容.
- 循環4 5 查詢
在java中用scroll查詢
1 @Test 2 public void scrollQueryTest() throws IOException { 3 // 1. 創建查詢對象 4 String index = "sms-logs-index"; 5 String type = "sms-logs-type"; 6 SearchRequest searchRequest = new SearchRequest(index);//指定索引 7 searchRequest.types(type);//指定類型 8 searchRequest.scroll(TimeValue.timeValueMinutes(1l));//指定存在內存的時長為1分鍾 9 // 2. 封裝查詢條件 10 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 11 searchSourceBuilder.sort("fee", SortOrder.DESC); 12 searchSourceBuilder.size(2); 13 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); 14 searchRequest.source(searchSourceBuilder); 15 16 17 // 3.執行查詢 18 // client執行 19 HttpHost httpHost = new HttpHost("192.168.43.30", 9200); 20 RestClientBuilder restClientBuilder = RestClient.builder(httpHost); 21 RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder); 22 23 SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); 24 String scrollId = searchResponse.getScrollId(); 25 System.out.println(scrollId);//獲取scorllId 26 27 28 // 4.獲取數據 29 SearchHit[] hits = searchResponse.getHits().getHits(); 30 for(SearchHit searchHit : hits){ 31 System.out.println(searchHit); 32 } 33 34 //獲取全部的下一頁, 不過我不知道這種有什么用????? 35 while (true){ 36 //創建SearchScrollRequest對象 37 SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId); 38 searchScrollRequest.scroll(TimeValue.timeValueMinutes(1l));//設置1分鍾 39 SearchResponse scroll = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT); 40 SearchHit[] hits1 = scroll.getHits().getHits(); 41 if(hits1 != null && hits1.length > 0){ 42 System.out.println("------------下一頁--------------"); 43 for(SearchHit searchHit : hits1){ 44 System.out.println(searchHit); 45 } 46 47 }else { 48 System.out.println("------------結束--------------"); 49 break; 50 } 51 } 52 53 //刪除ScrollId 54 ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); 55 clearScrollRequest.addScrollId(scrollId); 56 ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT); 57 System.out.println("刪除scroll" + clearScrollResponse); 58 }