這篇文章主要介紹“如何解決ES深度分頁問題”,在日常操作中,相信很多人在如何解決ES深度分頁問題問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”如何解決ES深度分頁問題”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括文山州網(wǎng)站建設(shè)、文山州網(wǎng)站制作、文山州網(wǎng)頁制作以及文山州網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,文山州網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到文山州省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
ES深度分頁問題:
ES 默認(rèn)采用的分頁方式是 from+ size 的形式,類似于MySQL的分頁offset+limit。當(dāng)請(qǐng)求數(shù)據(jù)量比較大時(shí),Elasticsearch會(huì)對(duì)分頁做出限制,因?yàn)榇藭r(shí)性能消耗會(huì)很大。例如查詢1000條數(shù)據(jù),假設(shè)我們有5個(gè)分片,那么每個(gè)shard都需要返回1000條數(shù)據(jù)給 coordinating node,而 coordinating node 需要接收 5*1000 條數(shù)據(jù),進(jìn)行排序后返回1000條數(shù)據(jù)給客戶端。即使每條數(shù)據(jù)只有 _doc _id 和 _score,這數(shù)據(jù)量也很大了,如果請(qǐng)請(qǐng)求量很大的情況下,很容易造成ES的OOM。ES中有個(gè)設(shè)置
index.max_result_window
,默認(rèn)是10000條數(shù)據(jù),如果分頁的數(shù)據(jù)超過第1萬條,就拒絕返回結(jié)果了。如果集群配置比較好,查詢請(qǐng)求量不是特別大,可以適當(dāng)?shù)姆糯筮@個(gè)參數(shù)。
解決方案:
1:使用scroll遍歷
scroll 分為初始化和遍歷兩步,初始化時(shí)將所有符合搜索條件的搜索結(jié)果緩存起來,可以想象成快照,在遍歷時(shí),從這個(gè)快照里取數(shù)據(jù),也就是說,在初始化后對(duì)索引插入、刪除、更新數(shù)據(jù)都不會(huì)影響遍歷結(jié)果。因此,scroll 并不適合用來做實(shí)時(shí)搜索,而更適用于后臺(tái)批處理任務(wù)等
API說明:
1)初始化
POST /book/_search?scroll=1m&size=2 { "query": { "match_all": {}} }
遍歷
GET /_search/scroll { "scroll": "1m", "scroll_id" : "步驟1中查詢出來的值" }
使用java RestHighLevelClient
代碼參考如下:
@Autowired private RestHighLevelClient restHighLevelClient; public Result<GoodsDTo> scrollSearch(...查詢參數(shù)){ BoolQueryBuilder queryBuilder.te = QueryBuilders.boolQuery(); //添加自己的搜索條件.... queryBuilder.must(QueryBuilders.termQuery("type", "商品所屬分類); queryBuilder.must(QueryBuilders.matchQuery("name", "商品名稱"); //搜索 SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource(); searchSourceBuilder.query(queryBuilder); //排序 searchSourceBuilder.sort(SortBuilders.fieldSort("order").order(SortOrder.DESC)); //搜索結(jié)果 SearchResponse searchResponse = null; //根據(jù)實(shí)際情況,判斷是多次調(diào)用還是一次while遍歷查詢?nèi)? if (StringUtils.isBlank("scrollId")) { //首屏 searchSourceBuilder.size("每次查詢的條數(shù)"); SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("索引名").source(searchSourceBuilder); searchRequest.scroll(new Scroll(TimeValue.timeValueMinutes(scrollKeepAliveTime))); searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); } else { //后續(xù)根據(jù)上次的id滾動(dòng) SearchScrollRequest searchScrollRequest = new SearchScrollRequest("scrollId"); searchScrollRequest.scroll(new Scroll(TimeValue.timeValueMinutes(scrollKeepAliveTime))); searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT); } SearchHit[] hits = searchResponse.getHits().getHits(); //根據(jù)業(yè)務(wù)需求,處理搜索結(jié)果 GoodsDTO result= handleSearchData(hits); //scrollId,往下滾動(dòng)需要使用 String scrollId = searchResponse.getScrollId(); return Result.succcess(result); }
2:使用search after
滿足實(shí)時(shí)獲取下一頁的文檔信息,search_after 分頁的方式是根據(jù)上一頁的最后一條數(shù)據(jù)來確定下一頁的位置,同時(shí)在分頁請(qǐng)求的過程中,如果有索引數(shù)據(jù)的增刪改,這些變更也會(huì)實(shí)時(shí)的反映到游標(biāo)上,這種方式是在es-5.X之后才提供的。為了找到每一頁最后一條數(shù)據(jù),每個(gè)文檔的排序字段必須有一個(gè)全局唯一值使用 _id 就可以了。
API說明:
GET /book/_search { "query": {"match_all": {}}, "size": 2, "sort": [{"_id": "desc"}] } GET /book/_search { "query": {"match_all": {}}, "size": 2, "search_after": [3], "sort": [{"_id": "desc"}] }
下一頁的數(shù)據(jù)依賴上一頁的最后一條的信息 所以不能跳頁
使用java RestHighLevelClient
代碼參考如下:
@Autowired private RestHighLevelClient restHighLevelClient; public Result<GoodsDTo> searchAfter(...查詢參數(shù)){ SearchRequest searchRequest = new SearchRequest(index); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(...搜索條件); searchSourceBuilder.size(1000); searchSourceBuilder.sort("_id", SortOrder.ASC); searchSourceBuilder.searchAfter("上一頁最后一條數(shù)據(jù)的id"); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] hits = searchResponse.getHits().getHits(); //根據(jù)業(yè)務(wù)需求,處理搜索結(jié)果 GoodsDTO result= handleSearchData(hits); return Result.succcess(result); }
到此,關(guān)于“如何解決ES深度分頁問題”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
網(wǎng)站欄目:如何解決ES深度分頁問題
標(biāo)題URL:http://sd-ha.com/article16/jochdg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、品牌網(wǎng)站制作、服務(wù)器托管、微信小程序、面包屑導(dǎo)航、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)