elasticsearch 分頁查詢實現(xiàn)方案

1. from+size 實現(xiàn)分頁

from表示從第幾行開始,size表示查詢多少條文檔坊秸。from默認為0踱蠢,size默認為10,
注意:size的大小不能超過index.max_result_window這個參數(shù)的設(shè)置咪辱,默認為10,000振劳。
如果搜索size大于10000,需要設(shè)置index.max_result_window參數(shù)

PUT _settings
{
    "index": {
        "max_result_window": "10000000"
    }
}          

內(nèi)部執(zhí)行原理:
示例:有三個節(jié)點node1油狂、node2历恐、node3,每個節(jié)點上有2個shard分片

node1 node2 node3
shard1 shard3 shard5
shard2 shard4 shard6
1.client發(fā)送分頁查詢請求到node1(coordinating node)上专筷,node1建立一個大小為from+size的優(yōu)先級隊列來存放查詢結(jié)果弱贼;
2.node1將請求廣播到涉及到的shards上;
3.每個shards在內(nèi)部執(zhí)行查詢磷蛹,把from+size條記錄存到內(nèi)部的優(yōu)先級隊列(top N表)中吮旅;
4.每個shards把緩存的from+size條記錄返回給node1;
5.node1獲取到各個shards數(shù)據(jù)后味咳,進行合并并排序庇勃,選擇前面的 from + size 條數(shù)據(jù)存到優(yōu)先級隊列,以便 fetch 階段使用槽驶。

各個分片返回給 coordinating node 的數(shù)據(jù)用于選出前 from + size 條數(shù)據(jù)责嚷,所以,只需要返回唯一標記 doc 的 _id 以及用于排序的 _score 即可掂铐,這樣也可以保證返回的數(shù)據(jù)量足夠小罕拂。
coordinating node 計算好自己的優(yōu)先級隊列后揍异,query 階段結(jié)束,進入 fetch 階段爆班。
from+size在深度分頁時衷掷,會帶來嚴重的性能問題:
CPU、內(nèi)存柿菩、IO戚嗅、網(wǎng)絡(luò)帶寬
數(shù)據(jù)量越大,越往后翻頁碗旅,性能越低

2.scroll

可以把 scroll 理解為關(guān)系型數(shù)據(jù)庫里的 cursor渡处,因此,scroll 并不適合用來做實時搜索祟辟,而更適用于后臺批處理任務(wù)颜价,比如群發(fā)骆莹。
可以把 scroll 分為初始化和遍歷兩步蚜印,
初始化時將所有符合搜索條件的搜索結(jié)果緩存起來循捺,可以想象成快照,
遍歷時吼具,從這個快照里取數(shù)據(jù)僚纷,也就是說,在初始化后對索引插入拗盒、刪除怖竭、更新數(shù)據(jù)都不會影響遍歷結(jié)果。

1.初始化:

POST http://192.168.18.230:9200/bill/bill/_search?scroll=3m
{
    "query": { "match_all": {}},
    "size": 10 
}

參數(shù) scroll陡蝇,表示暫存搜索結(jié)果的時間
返回一個 _scroll_id痊臭,_scroll_id 用來下次取數(shù)據(jù)用

2.遍歷:

POST http://192.168.18.230:9200/_search?scroll=3m
{
  "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAHRCFi1BLWIzSHdhUkl1cC1rcjBueVhJZUEAAAAAAAB0QRYtQS1iM0h3YVJJdXAta3IwbnlYSWVBAAAAAAAAdEQWLUEtYjNId2FSSXVwLWtyMG55WEllQQAAAAAAAHRDFi1BLWIzSHdhUkl1cC1rcjBueVhJZUEAAAAAAAB0RRYtQS1iM0h3YVJJdXAta3IwbnlYSWVB"
}

這里的 scroll_id 即 上一次遍歷取回的 _scroll_id 或者是初始化返回的 _scroll_id,同樣的登夫,需要帶 scroll 參數(shù)广匙。
注意,每次都要傳參數(shù) scroll恼策,刷新搜索結(jié)果的緩存時間鸦致。另外,不需要指定 index 和 type涣楷。

3.search_after

官網(wǎng)上的說明:

The Scroll api is recommended for efficient deep scrolling but scroll contexts are costly and it is not recommended to use it for real time user requests. 
The search_after parameter circumvents this problem by providing a live cursor. The idea is to use the results from the previous page to help the retrieval of the next page.

Scroll 被推薦用于深度查詢分唾,但是contexts的代價是昂貴的,不推薦用于實時用戶請求总棵,而更適用于后臺批處理任務(wù)鳍寂,比如群發(fā)。
search_after 提供了一個實時的光標來避免深度分頁的問題情龄,其思想是使用前一頁的結(jié)果來幫助檢索下一頁迄汛。

search_after 需要使用一個唯一值的字段作為排序字段,否則不能使用search_after方法
推薦使用_uid 作為唯一值的排序字段

GET twitter/tweet/_search
{
    "size": 10,
    "query": { "match_all": {}},
    "sort": [
        {"date": "asc"},
        {"_uid": "desc"}
    ]
}

每一條返回記錄中會有一組 sort values 骤视,查詢下一頁時鞍爱,在search_after參數(shù)中指定上一頁返回的 sort values

GET twitter/tweet/_search
{
    "size": 10,
    "query": { "match_all": {}},
    "search_after": [1463538857, "tweet#654323"],
    "sort": [
        {"date": "asc"},
        {"_uid": "desc"}
    ]
}

注意:search_after不能自由跳到一個隨機頁面,只能按照 sort values 跳轉(zhuǎn)到下一頁

4.總結(jié)

  • 深度分頁不管是關(guān)系型數(shù)據(jù)庫還是Elasticsearch還是其他搜索引擎专酗,都會帶來巨大性能開銷睹逃,特別是在分布式情況下。
  • 有些問題可以考業(yè)務(wù)解決而不是靠技術(shù)解決祷肯,比如很多業(yè)務(wù)都對頁碼有限制沉填,google 搜索,往后翻到一定頁碼就不行了佑笋。
  • scroll 并不適合用來做實時搜索翼闹,而更適用于后臺批處理任務(wù),比如群發(fā)蒋纬。
  • search_after不能自由跳到一個隨機頁面猎荠,只能按照 sort values 跳轉(zhuǎn)到下一頁。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜀备,一起剝皮案震驚了整個濱河市关摇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碾阁,老刑警劉巖输虱,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脂凶,居然都是意外死亡宪睹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門艰猬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來横堡,“玉大人,你說我怎么就攤上這事冠桃∶” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵食听,是天一觀的道長胸蛛。 經(jīng)常有香客問我,道長樱报,這世上最難降的妖魔是什么葬项? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮迹蛤,結(jié)果婚禮上民珍,老公的妹妹穿的比我還像新娘襟士。我一直安慰自己,他們只是感情好嚷量,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布陋桂。 她就那樣靜靜地躺著,像睡著了一般蝶溶。 火紅的嫁衣襯著肌膚如雪嗜历。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天抖所,我揣著相機與錄音梨州,去河邊找鬼。 笑死田轧,一個胖子當著我的面吹牛暴匠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涯鲁,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼巷查,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抹腿?” 一聲冷哼從身側(cè)響起岛请,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎警绩,沒想到半個月后崇败,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡肩祥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年后室,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片混狠。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡岸霹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出将饺,到底是詐尸還是另有隱情贡避,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布予弧,位于F島的核電站刮吧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掖蛤。R本人自食惡果不足惜杀捻,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚓庭。 院中可真熱鬧致讥,春花似錦仅仆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拳魁。三九已至惶桐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間潘懊,已是汗流浹背姚糊。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留授舟,地道東北人救恨。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像释树,于是被迫代替她去往敵國和親肠槽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 聲明:本文轉(zhuǎn)自我的個人博客奢啥,有興趣的可以查看原文秸仙。轉(zhuǎn)發(fā)請注明來源。 背景 Elasticsearch 是一個實時的...
    此星爺非彼星爺閱讀 1,931評論 0 3
  • 前兩天突然被業(yè)務(wù)部的同事問了一句:“我現(xiàn)在要做搜索結(jié)果全量導(dǎo)桩盲,該用哪個接口寂纪,性能要好的?”之前雖然是知道這三種方法...
    華安火車迷閱讀 24,835評論 27 35
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法赌结,類相關(guān)的語法捞蛋,內(nèi)部類的語法,繼承相關(guān)的語法柬姚,異常的語法拟杉,線程的語...
    子非魚_t_閱讀 31,623評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)量承,斷路器搬设,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 你有沒有這樣一段時間焕梅,很焦慮,很焦慮卦洽。 每天睜開眼贞言,任務(wù)滿天飛,雜事后面催阀蒂。一路跑啊一路追该窗,天黑還有一大堆弟蚀。事事催...
    笑忘書800閱讀 368評論 0 4