timeout機制
如果查詢我們需要的所有資料時間很長,可以先返回查詢到的一部分資料,就需要timeout機制。
timeout機制,指定每個shard,只能在timeout時間範圍內,將搜尋到的部分資料(也可能全部搜尋到),直接返回給client程式,而不是等到所有的資料都搜尋出來之後再返回。
預設情況下,沒有timeout機制。
程式碼示例
GET test_index/test_type/_search?timeout=10ms
複製程式碼
分頁搜尋
語法:
1GET test_index/test_type/_search?from=0&size=6
複製程式碼deep paging
Elasticsearch 的分頁查詢在資料小於50000條還是不錯的,預設每頁10條資料,也就是在5000頁以內,但時當資料超過50000條的話,就會出現深分頁問題,也就是 deep paging。
舉個例子,總共有60000條資料,現在有3個primary shard,每個shard上分20000條,每頁是10條資料,我們要搜尋第1000頁,實際上要拿到的是10001-10010,es會從3個shard上每個都拿10010條資料,然後對著30030條資料排序,取第10001-10010條資料。
這樣當資料很大,搜尋過深的時候,在協調節點即 cordinate node 上會儲存大量的資料,並且還要進行排序,排序之後,再取出我們需要的那一頁。這個過程,耗費網路頻寬,記憶體和CPU,影響效能。
解決 deep paging 問題
為了解決上面的問題,elasticsearch提出了一個scroll滾動的方式,這個滾動的方式原理就是通過每次查詢後,返回一個scroll_id。根據這個scroll_id 進行下一頁的查詢。可以把這個scroll_id理解為通常關係型資料庫中的遊標。但是,這種scroll方式的缺點是不能夠進行反覆查詢,也就是說,只能進行下一頁,不能進行上一頁。
scroll 使用
使用scoll滾動搜尋,可以先搜尋一批資料,然後下次再搜尋一批資料,以此類推,直到搜尋出全部的資料來。
scoll搜尋會在第一次搜尋的時候,儲存一個當時的檢視快照,之後只會基於該舊的檢視快照提供資料搜尋,如果這個期間資料變更,是不會讓使用者看到的
採用基於_doc進行排序的方式,效能較高scoll,看起來挺像分頁的,但是其實使用場景不一樣。分頁主要是用來一頁一頁搜尋,給使用者看的;scoll主要是用來一批一批檢索資料,讓系統進行處理的
查詢示例:
1GET test_index/test_type/_search?scroll=1m
2{
3 "query": {
4 "match_all": {}
5 },
6 "size": 3
7}
複製程式碼查詢所有資料,一次返回三條資料,返回結果
1{
2 "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAEq3Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABKuxZNd25KaFhQRVFiMkNFcUdYYTNWNGtnAAAAAAAASroWTXduSmhYUEVRYjJDRXFHWGEzVjRrZwAAAAAAAEq5Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABKuBZNd25KaFhQRVFiMkNFcUdYYTNWNGtn",
3 "took": 0,
4 "timed_out": false,
5 "_shards": {
6 "total": 5,
7 "successful": 5,
8 "skipped": 0,
9 "failed": 0
10 },
11 "hits": {
12 "total": 9,
13 "max_score": 1,
14 "hits": [
15 {
16 "_index": "test_index",
17 "_type": "test_type",
18 "_id": "AWjxCRPzFjHDLA-cm71O",
19 "_score": 1,
20 "_source": {
21 "test_field": "create id by es"
22 }
23 },
24 {
25 "_index": "test_index",
26 "_type": "test_type",
27 "_id": "5",
28 "_score": 1,
29 "_source": {
30 "test_field": "external client2 changed"
31 }
32 },
33 {
34 "_index": "test_index",
35 "_type": "test_type",
36 "_id": "8",
37 "_score": 1,
38 "_source": {
39 "test_field": "create id 6"
40 }
41 }
42 ]
43 }
44}
複製程式碼獲得的結果會有一個scoll_id,下一次再傳送scoll請求的時候,必須帶上這個scoll_id
1GET _search/scroll
2{
3 "scroll": "1m",
4 "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAEs0Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABLOBZNd25KaFhQRVFiMkNFcUdYYTNWNGtnAAAAAAAASzYWTXduSmhYUEVRYjJDRXFHWGEzVjRrZwAAAAAAAEs1Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABLNxZNd25KaFhQRVFiMkNFcUdYYTNWNGtn"
5}
複製程式碼