Java中Elasticsearch 實現(xiàn)分頁方式(三種方式)
ES 簡介
Elasticsearch 是一個基于 Lucene 實現(xiàn)的搜索服務(wù)器。它提供了一個分布式多用戶能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch是用Java語言開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是一種流行的企業(yè)級搜索引擎。Elasticsearch用于云計算中,能夠達到實時搜索,穩(wěn)定,可靠,快速,安裝使用方便。
ES 的特點:
分布式實時文件存儲,可以將每一個字段都編入索引,使其可以被檢索
可以作為一個大型分布式集群(數(shù)百臺服務(wù)器)技術(shù),處理PB級數(shù)據(jù)
Elasticsearch不是什么新技術(shù),主要是將全文檢索、數(shù)據(jù)分析以及分布式技術(shù),合并在了一起,才形成了獨一無二的ES。
下面介紹下Java中Elasticsearch 實現(xiàn)分頁的 3 種方式,還有誰不會??
一、from + size 淺分頁
"淺"分頁可以理解為簡單意義上的分頁。
它的原理很簡單,就是查詢前20條數(shù)據(jù),然后截斷前10條,只返回10-20的數(shù)據(jù)。這樣其實白白浪費了前10條的查詢。
GET test_dev/_search { "query": { "bool": { "filter": [ { "term": { "age": 28 } } ] } }, "size": 10, "from": 20, "sort": [ { "timestamp": { "order": "desc" }, "_id": { "order": "desc" } } ] }
其中,from定義了目標(biāo)數(shù)據(jù)的偏移值,size定義當(dāng)前返回的數(shù)目。默認(rèn)from為0,size為10,即所有的查詢默認(rèn)僅僅返回前10條數(shù)據(jù)。
在這里有必要了解一下from/size的原理:
因為es是基于分片的,假設(shè)有5個分片,from=100,size=10。則會根據(jù)排序規(guī)則從5個分片中各取回100條數(shù)據(jù)數(shù)據(jù),然后匯總成500條數(shù)據(jù)后選擇最后面的10條數(shù)據(jù)。
做過測試,越往后的分頁,執(zhí)行的效率越低。總體上會隨著from的增加,消耗時間也會增加。而且數(shù)據(jù)量越大,就越明顯!
二、scroll 深分頁
from+size查詢在10000-50000條數(shù)據(jù)(1000到5000頁)以內(nèi)的時候還是可以的,但是如果數(shù)據(jù)過多的話,就會出現(xiàn)深分頁問題。
為了解決上面的問題,elasticsearch提出了一個scroll滾動的方式。
scroll 類似于sql中的cursor,使用scroll,每次只能獲取一頁的內(nèi)容,然后會返回一個scroll_id
。根據(jù)返回的這個scroll_id
可以不斷地獲取下一頁的內(nèi)容,所以scroll并不適用于有跳頁的情景。
GET test_dev/_search?scroll=5m { "query": { "bool": { "filter": [ { "term": { "age": 28 } } ] } }, "size": 10, "from": 0, "sort": [ { "timestamp": { "order": "desc" }, "_id": { "order": "desc" } } ] }
scroll=5m
表示設(shè)置scroll_id
保留5分鐘可用。- 使用scroll必須要將from設(shè)置為0。
- size決定后面每次調(diào)用
_search
搜索返回的數(shù)量
然后我們可以通過數(shù)據(jù)返回的_scroll_id
讀取下一頁內(nèi)容,每次請求將會讀取下10條數(shù)據(jù),直到數(shù)據(jù)讀取完畢或者scroll_id
保留時間截止:
GET _search/scroll { "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAJZ9Fnk1d......", "scroll": "5m" }
注意:請求的接口不再使用索引名了,而是 _search/scroll
,其中GET和POST方法都可以使用。
scroll刪除
根據(jù)官方文檔的說法,scroll的搜索上下文會在scroll的保留時間截止后自動清除,但是我們知道scroll是非常消耗資源的,所以一個建議就是當(dāng)不需要了scroll數(shù)據(jù)的時候,盡可能快的把scroll_id
顯式刪除掉。
清除指定的scroll_id
:
DELETE _search/scroll/DnF1ZXJ5VGhlbkZldGNo.....
清除所有的scroll:
DELETE _search/scroll/_all
三、search_after 深分頁
scroll 的方式,官方的建議不用于實時的請求(一般用于數(shù)據(jù)導(dǎo)出),因為每一個 scroll_id
不僅會占用大量的資源,而且會生成歷史快照,對于數(shù)據(jù)的變更不會反映到快照上。
search_after
分頁的方式是根據(jù)上一頁的最后一條數(shù)據(jù)來確定下一頁的位置,同時在分頁請求的過程中,如果有索引數(shù)據(jù)的增刪改查,這些變更也會實時的反映到游標(biāo)上。但是需要注意,因為每一頁的數(shù)據(jù)依賴于上一頁最后一條數(shù)據(jù),所以無法跳頁請求。
為了找到每一頁最后一條數(shù)據(jù),每個文檔必須有一個全局唯一值,官方推薦使用 _uid
作為全局唯一值,其實使用業(yè)務(wù)層的 id 也可以。
GET test_dev/_search { "query": { "bool": { "filter": [ { "term": { "age": 28 } } ] } }, "size": 20, "from": 0, "sort": [ { "timestamp": { "order": "desc" }, "_id": { "order": "desc" } } ] }
- 使用
search_after
必須要設(shè)置from=0
。 - 這里我使用timestamp和
_id
作為唯一值排序。 - 我們在返回的最后一條數(shù)據(jù)里拿到sort屬性的值傳入到
search_after
。
使用sort返回的值搜索下一頁:
GET test_dev/_search { "query": { "bool": { "filter": [ { "term": { "age": 28 } } ] } }, "size": 10, "from": 0, "search_after": [ 1541495312521, "d0xH6GYBBtbwbQSP0j1A" ], "sort": [ { "timestamp": { "order": "desc" }, "_id": { "order": "desc" } } ] }
到此這篇關(guān)于Elasticsearch 實現(xiàn)分頁的 3 種方式,還有誰不會??的文章就介紹到這了,更多相關(guān)Elasticsearch 實現(xiàn)分頁內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java查詢Elasticsearch數(shù)據(jù)根據(jù)指定id檢索(in查詢)、sql權(quán)限過濾、多字段匹配檢索及數(shù)據(jù)排序
- Java使用ES?Client?調(diào)用滾動查詢及Elasticsearch滾動查詢Scrolling機制
- Java?Api實現(xiàn)Elasticsearch的滾動查詢功能
- Java利用ElasticSearch實現(xiàn)自動補全功能
- Java+ElasticSearch+Pytorch實現(xiàn)以圖搜圖功能
- 關(guān)于Java中配置ElasticSearch集群環(huán)境賬號密碼的問題
- Java如何使用elasticsearch進行模糊查詢
- JAVA使用ElasticSearch查詢in和not in的實現(xiàn)方式
- JAVA操作elastic search的詳細(xì)過程
相關(guān)文章
Spring Boot優(yōu)雅使用RocketMQ的方法實例
這篇文章主要給大家介紹了關(guān)于Spring Boot優(yōu)雅使用RocketMQ的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Java web實現(xiàn)動態(tài)圖片驗證碼的示例代碼
這篇文章主要介紹了Java web實現(xiàn)動態(tài)圖片驗證碼的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Mybatis Plus條件構(gòu)造器ConditionConstructor用法實例解析
這篇文章主要介紹了Mybatis Plus條件構(gòu)造器ConditionConstructor用法實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08eclipse實現(xiàn)ElGamal數(shù)字簽名
這篇文章主要為大家詳細(xì)介紹了eclipse實現(xiàn)ElGamal數(shù)字簽名,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-06-06SpringBoot整合Caffeine實現(xiàn)本地緩存的實踐分享
緩存是提升系統(tǒng)性能的一個不可或缺的工具,通過緩存可以避免大部分重復(fù)的請求到數(shù)據(jù)庫層,減少IO鏈接次數(shù),提升整體的響應(yīng)速率,本地緩存中比較常見的比如 Caffeine 緩存,這篇文章將結(jié)合具體的 Springboot 項目搭配 Caffeine 實現(xiàn)本地緩存的各種使用方式2024-07-07