你還不會ElasticsSearch分頁查詢?那你看這一篇就夠了,快拿走!
關注【 大資料之美 】公眾號 和你一起成長 回覆【999】入群
點選連結:加入我們,一起動手實踐真實大資料專案
引言
我們使用mysql的時候經常遇到分頁查詢的場景,在mysql中使用limit關鍵字來實現分頁。比如下面的示例
select * from orders where category='man' limit 100,100;
ElasticsSearch 同樣也有很多分頁查詢的場景,特別是在資料量比較大,而且查詢條件比較複雜的情況下。在 mysql 中如果在某種無法命中索引的情況下,可以選擇使用ES的分頁查詢進行功能替換。
ES實現分頁查詢有幾種不同的方案,每種方案都有自己的優缺點,下面就帶你領略一下 ES 分頁查詢的魅力吧。
1、from/size方案
ES 分頁最常用的一種方案,類似 mysql 裡的limit,from指定查詢的起始位置,size表示從起始位置開始的文件數量,如下基礎查詢:
GET kibana_sample_data_flights/_search
其中:
- from:未指定,預設值是 0,注意不是1,代表當前頁返回資料的起始值。
- size:未指定,預設值是 10,代表當前頁返回資料的條數。
- 預設返回前10個匹配的匹配項。
優缺點
- 優點:支援隨機翻頁,
- 缺點:受制於 max_result_window 設定,不能無限制翻頁,越往後翻頁越慢,存在深度翻頁問題。
適用場景
- 非常適合小型資料集或者大資料集返回 Top N結果集的業務場景
- 支援隨機跳轉分頁的業務場景
2、search_after 查詢
有時候我們會遇到一些業務場景,需要進行很深度的分頁,但是可以不指定頁數翻頁,只要可以實時請求下一頁就行。比如一些無限下拉的瀑布流頁面。 search_after 查詢方案是使用前一頁中的一組排序值來檢索匹配的下一頁。利用實時有遊標來幫我們解決實時滾動的問題,簡單來說前一次查詢的結果會返回一個唯一的字串,下次查詢帶上這個字串,進行下一頁的查詢。 類似下面這個查詢:
GET /_search { "size" : 2, "sort": [ { "order_datetime": "desc", "_id": "asc" } ] }
查詢結果的最後,有個sort的json結構:
"sort": [
1704147780000,
"um1362393"
]
這裡記錄了上一次查詢的位置,所以當在查詢下一頁時,只要把這些值帶上就可以實現。
GET /_search
{
"size" : 2,
"sort": [
{
"order_datetime": "desc",
"_id": "asc"
}
],
"search_after": [
1704147780000,
"um1362393"
]
}
就這樣一直操作就可以實現不斷的檢視下一頁了。很顯然,這個查詢操作的開銷會很小,但是缺點就是無法進行隨機翻頁,可以類比連結串列和陣列。
3、Scroll 遍歷查詢
相比於 from/size 和 search_after 返回一頁資料,Scroll API 可用於從單個搜尋請求中檢索大量結果。但是 scroll 滾動遍歷查詢是非實時的,資料量大的時候,響應時間可能會比較長。
示例如下:
POST /_search?scroll=3m
{
"size": 100,
"query": {
"match": {
"host": "elastic"
}
}
}
首先第一次查詢後,會生成一個當前查詢條件結果的快照,後面的每次叫翻頁都是基於這個快照的結果,也就是即使有新的資料進來也不會被查詢到。
上面這個查詢結果會返回一個scroll_id,拷貝過來,組成下一條查詢語句
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFlNpZU5wVVhoUlhHd0NqNEhsNktKQmcAAAAACz8y-xZ3SFBodGo1MVJNdV9UN21jMmo5aGd3"
}
以此類推,後面每次滾屏都把前一個的scroll_id
複製過來。注意到,後續請求時沒有了index資訊,size資訊等,這些都在初始請求中,只需要使用scroll_id和scroll兩個引數即可。
總結
- from/size方案的優點是簡單,缺點是在深度分頁的場景下系統開銷比較大。
- search after 可以實時高效的進行分頁查詢,但是隻能做下一頁的查詢場景,不能進行隨機頁數查詢。
- scroll方案基於快照,不能用在高實時性的場景下,建議用在類似資料匯出場景下使用。
關注【 大資料之美 】公眾號 和你一起成長 回覆【999】入群本次分享就到這裡,希望你能有所收穫。碼字不易,歡迎點贊關注。