2017-10-06 49 views
1

我有點困惑Elasticsearch的滾動功能。 在elasticsearch中,每當用戶滾動結果集時,都可以調用搜索API? 從技術文檔Elasticsearch滾動

"search_type" => "scan", // use search_type=scan 
"scroll" => "30s",   // how long between scroll requests. should be small! 
"size" => 50,    // how many results *per shard* you want back 

是不是意味着它會爲每30秒進行搜索,並返回結果的所有集合,直到有沒有記錄?

例如,我的ES返回500條記錄。我從ES獲得的數據是兩組記錄,每組記錄有250條記錄。有什麼辦法可以首先顯示第一組250條記錄,當用戶滾動第二組250條記錄時。請建議

回答

0

您正在理解錯誤的scroll屬性的目的。這並不意味着elasticsearch將在30秒後獲取下一頁數據。當你在做第一次滾動請求時,你需要指定什麼時候應該關閉滾動上下文。 scroll參數告訴在30秒後關閉滾動上下文。

做完第一次滾動請求後,您將返回scroll_id參數作爲響應。對於下一頁,您需要傳遞該值以獲取滾動響應的下一頁。如果您不會在30秒內完成下一個滾動請求,滾動請求將被關閉,您將無法獲得該滾動請求的下一頁。

1

您所描述的示例用例實際上是search results pagination,它可用於任何搜索查詢並受到10k結果的限制。 scroll需要請求的情況下,當你需要超過10K的限制,與scroll查詢你甚至可以獲取整個文件集合。

大概這裏混亂的源是scroll術語是不明確的:它意味着一個查詢的類型,並且也是這樣的查詢的參數的名稱(如在other comments所提到的,它是時間ES將保持等着你去抓下一個滾動塊)。

scroll查詢是沉重的,並且應該避免,直到絕對必要的。事實上,在docs 它說:

滾動不用於實時用戶的請求,而是爲了處理大量的數據,...

現在關於你的另一個問題:

在elasticsearch中,每當用戶滾動結果集時,都可以調用搜索API嗎?

是的,即使若干parallel scroll requests 是可能的:

每個渦管是獨立的,可以在像任何滾動請求並行處理。

1

你所尋找的是分頁。

您可以通過查詢一個固定尺寸和設置from參數實現你的目標。由於您要分批顯示250個結果,因此您可以設置size = 250以及每個連續查詢,將from的值遞增250

GET /_search?size=250      ---- return first 250 results 
GET /_search?size=250&from=250   ---- next 250 results 
GET /_search?size=250&from=500   ---- next 250 results 

相反,Scan & scroll可以檢索到大量具有單一的搜索結果,是理想意味着像重新索引數據業務併入一個新的索引。不建議使用它來實時顯示搜索結果。

爲了簡要解釋Scan & scroll,它實質上做的是掃描提供掃描請求的查詢的索引並返回scrol_id。可以將此scroll_id傳遞給下一個滾動請求以返回下一批結果。

考慮happen-

  • 滾輪被初始化以下示例 -

    # Initialize the scroll 
    page = es.search(
        index = 'yourIndex', 
        doc_type = 'yourType', 
        scroll = '2m', 
        search_type = 'scan', 
        size = 1000, 
        body = { 
        # Your query's body 
        }) 
        sid = page['_scroll_id'] 
        scroll_size = page['hits']['total'] 
    
        # Start scrolling 
        while (scroll_size > 0): 
        print "Scrolling..." 
        page = es.scroll(scroll_id = sid, scroll = '2m') 
        # Update the scroll ID 
        sid = page['_scroll_id'] 
        # Get the number of results that we returned in the last scroll 
        scroll_size = len(page['hits']['hits']) 
        print "scroll size: " + str(scroll_size) 
        # Do something with the obtained page 
    

    在上面的例子中,下面的事件。這將返回第一批結果以及scroll_id

  • 對於每個後續滾動請求,會發送更新的scroll_id(在前一個滾動請求中收到)並返回下一批結果。
  • 滾動時間基本上是搜索上下文保持活動的時間。如果在設定的時間範圍內未發送下一個滾動請求,搜索上下文將丟失,結果將不會返回。這就是爲什麼它不應該用於具有大量文檔的索引的實時結果顯示。