Version:6.1javascript
英文原文地址:Scrollhtml
當一個搜索請求返回單頁結果時,可使用 scroll API 檢索體積大量(甚至所有)結果,這和在傳統數據庫中使用遊標的方式很是類似。java
不要把 scroll
用於實時請求,它主要用於大數據量的場景。例如:將一個索引的內容索引到另外一個不一樣配置的新索引中。node
一些官方支持的客戶端提供了一些輔助類,能夠協助滾動搜索和索引之間的文檔重索引:web
Perl數據庫
參閱 Search::Elasticsearch::Client::5_0::Bulk 和 Search::Elasticsearch::Client::5_0::Scrollapi
Python數組
參閱 elasticsearch.helpers.*緩存
NOTE:從 scroll 請求返回的結果反映了初始搜素請求生成時的索引狀態,就像時間快照同樣。對文檔的更改(索引、更新或者刪除)只會影響之後的搜索請求。session
爲了使用 scroll ,初始的搜索請求應該在查詢字符串中指定 scroll
參數,這個參數會告訴 Elasticsearch 將 「search context」 保存多久。例如:?scroll=1m
POST /twitter/_search?scroll=1m { "size": 100, "query": { "match" : { "title" : "elasticsearch" } } }
上面的請求返回的結果裏會包含一個 _scroll_id
,咱們須要把這個值傳遞給 scroll
API ,用來取回下一批結果。
POST /_search/scroll { "scroll" : "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" }
(1) GET
或者 POST
均可以
(2) URL 不能包含 index
和 type
名稱,原始請求中已經指定了
(3) scroll
參數告訴 Elasticsearch 把搜索上下文再保持一分鐘
(4) scroll_id
的值就是上一個請求中返回的 _scroll_id
的值
size
參數容許咱們配置每批結果返回的最大命中數。每次調用 scroll API 都會返回下一批結果,直到再也不有能夠返回的結果,即命中數組爲空。
IMPORTANT:初始的搜索請求和每一個 scroll 請求都會返回一個新的
_scroll_id
,只有最近的_scroll_id
是可用的
NOTE:若是請求指定了過濾,就只有初始搜索的響應中包含聚合結果。
NOTE:Scroll 請求對
_doc
排序作了優化。若是要遍歷全部的文檔,並且不考慮順序,_doc
是最高效的選項。
GET /_search?scroll=1m { "sort": [ "_doc" ] }
scroll
參數告訴了 Elasticsearch 應當保持搜索上下文多久。它的值不須要長到可以處理完全部的數據,只要足夠處理前一批結果就好了。每一個 scroll 請求都會設置一個新的過時時間。
一般,爲了優化索引,後臺合併進程會把較小的段合併在一塊兒建立出新的更大的段,此時會刪除較小的段。這個過程在 scrolling 期間會繼續進行,可是一個打開狀態的索引上下文能夠防止舊段在仍須要使用時被刪除。這就解釋了 Elasticsearch 爲何可以不考慮對文檔的後續修改,而返回初始搜索請求的結果。
TIP:使舊段保持活動狀態意味着須要更多的文件句柄。請確保你已將節點配置爲擁有足夠的可用的文件句柄。詳情參閱 File Descriptors
你可使用 nodes stats API 查看有多少搜索上下文處於開啓狀態
GET /_nodes/stats/indices/search
GET /_nodes/stats/indices/search
當超出了 scroll timeout
時,搜索上下文會被自動刪除。可是,保持 scrolls 打開是有成本的,當再也不使用 scroll 時應當使用 clear-scroll
API 進行顯式清除。
DELETE /_search/scroll { "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" }
可使用數組傳遞多個 scroll ID
DELETE /_search/scroll { "scroll_id" : [ "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==", "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB" ] }
使用 _all
參數清除全部的搜索上下文
DELETE /_search/scroll/_all
DELETE /_search/scroll/_all
也可使用 query string 參數傳遞 scroll_id
,多個值使用英文逗號分割
DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB
DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB
若是 scroll 查詢返回的文檔數量過多,能夠把它們拆分紅多個切片以便獨立使用
GET /twitter/_search?scroll=1m { "slice": { "id": 0, "max": 2 }, "query": { "match" : { "title" : "elasticsearch" } } } GET /twitter/_search?scroll=1m { "slice": { "id": 1, "max": 2 }, "query": { "match" : { "title" : "elasticsearch" } } }
(1) 切片的 id
(2) 最大切片數量
上面的栗子,第一個請求返回的是第一個切片(id : 0)的文檔,第二個請求返回的是第二個切片的文檔。由於咱們設置了最大切片數量是 2 ,因此兩個請求的結果等價於一次不切片的 scroll 查詢結果。默認狀況下,先在第一個分片(shard)上作切分,而後使用如下公式:slice(doc) = floorMod(hashCode(doc._uid), max) 在每一個 shard 上執行切分。例如,若是 shard 的數量是 2 ,而且用戶請求 4 slices ,那麼 id 爲 0 和 2 的 slice 會被分配給第一個 shard ,id 爲 1 和 3 的 slice 會被分配給第二個 shard 。
每一個 scroll 是獨立的,能夠像任何 scroll 請求同樣進行並行處理。
NOTE:若是 slices 的數量比 shards 的數量大,第一次調用時,slice filter 的速度會很是慢。它的複雜度時 O(n) ,內存開銷等於每一個 slice N 位,其中 N 時 shard 中的文檔總數。通過幾回調用後,篩選器會被緩存,後續的調用會更快。可是仍須要限制並行執行的 sliced 查詢的數量,以避免內存激增。
爲了徹底避免此成本,可使用另外一個字段的 doc_values
來進行切片,但用戶必須確保該字段具備如下屬性:
doc_values
GET /twitter/_search?scroll=1m { "slice": { "field": "date", "id": 0, "max": 10 }, "query": { "match" : { "title" : "elasticsearch" } } }
NOTE:默認狀況下,每一個 scroll 容許的最大切片數量時 1024。你能夠更新索引設置中的
index.max_slices_per_scroll
來繞過此限制。
POST /book1/_search?scroll=10m { "size":20 }
{ "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn", "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 41, "max_score": 1, "hits": [ { "_index": "book1", "_type": "english", "_id": "_update", "_score": 1, "_source": { "scripted_upsert": true, "script": { "id": "my_web_session_summariser", "params": { "pageViewEvent": { "url": "foo.com/bar", "response": 404, "time": "2014-01-01 12:32" } } }, "upsert": {} } }, { "_index": "book1", "_type": "english", "_id": "79", "_score": 1, "_source": { "name": "new_name" } } 。。。。 }
POST /_search/scroll { "scroll":"10m", "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn" }
最後一頁只有一條:
{ "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn", "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 41, "max_score": 1, "hits": [ { "_index": "book1", "_type": "english", "_id": "oAmI_mQBbhSmAk-TGrMQ", "_score": 1, "_source": { "name": "否sdfdsfds", "age": 13, "class": "dsfdsf", "addr": "中國" } } ] } }
繼續執行返回空:
{ "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn", "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 41, "max_score": 1, "hits": [] } }
SearchContextMissingException[No search context found for id [721283]];緣由:scroll設置的時間太短了。