2016-02-04 285 views
52

我們從Elasticsearch 2.1中檢索信息並允許用戶查看結果。當用戶請求高頁碼,我們得到了以下錯誤消息:Elasticsearch 2.1:結果窗口太大(index.max_result_window)

結果窗口過大,從+大小必須小於或等於 到:[10000]但[10020]。請參閱滾動API以獲得更高效的請求大型數據集的方式。此限制可通過改變設置的 [index.max_result_window]索引等級參數

彈性實況說,這是因爲高存儲器消耗和使用滾動API:

值更高比可以消耗大量的堆內存每 搜索和每個碎片執行搜索。這是最安全的離開這個 值,因爲它是一個用於任何滾動API深滾動https://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

的事情是,我不想檢索大型數據集。我只想從結果集中非常高的數據集中檢索切片。另外,滾動實況說:

滾動不用於實時用戶請求https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

這給我留下了一些問題:

1)請問內存的消耗實在是低(任如果是這樣的話)爲什麼如果我使用滾動api滾動到結果10020(並忽略低於10000的所有內容),而不是對結果10000-10020執行「正常」搜索請求?

2)似乎沒有滾動API是我的選擇,但我不得不增加「index.max_result_window」。有人對這個有經驗麼?

3)有沒有其他的選擇來解決我的問題?

回答

15

在彈性文檔深談尋呼以下頁面:

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

根據您的文件的大小,碎片的數量,以及您正在使用的 硬件, 10,000到50,000的結果(1,000到 5,000頁)深度應該是完全可行的。但是從 值來看,分類過程的確會變得非常重要,使用大量的CPU,內存和帶寬。出於這個原因,我們強烈建議 針對深度分頁。

+0

所以在這裏,我們應該放棄深度分頁,對吧?基本上,對於單個查看器來說,不存在分頁4000頁的含義。比方說,谷歌搜索,我們很難滾動到第8或第9頁檢查結果。通常我們只關注Google給我們的前3-5個頁面。 – dotslash

+2

如果我們需要深度分頁,我們可以使用滾動API嗎? –

+2

但是,當我們啓用排序功能時,可以在電子商務網站上說。當用戶想要查看價格最高的商品時。當我們按最高價格比較排序時,結果會有所不同,而當我們按最低頁面排序時,結果會有所不同,但最後一頁是正確的?因爲我們限制可以訪問的結果的數量。 任何解決此問題的方法? –

55

如果您需要大深分頁,我想的解決方案只有一個變種是增加值max_result_window

curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "index" : { "max_result_window" : 500000 } }' 

內存使用量的增加,我沒有發現的〜100K

+0

我有同樣的錯誤結果窗口太大,從+大小必須小於或等於:[10000],但是[47190]。請參閱滾動API以獲取更高效的請求大型數據集的方法。這個限制可以通過改變[index.max_result_window]索引級別參數來設置。')它說它有4719頁(每頁10個結果)。我認爲你的建議是有效的。 – dotslash

+0

對於小於500000的少量文檔,這是一個很好的解決方案 – Ezzat

+1

我正在使用ES v2.2.0,並且我必須將有效負載更改爲「{」max_result_window「:500000}」才能正常工作。所以curl命令變成了 - 'curl -XPUT「http:// localhost:9200/my_index/_settings」-d'{「max_result_window」:500000}'' –

2

使用滾動API可以獲得10000個以上的結果。

Scroll example in ElasticSearch NEST API

我已經用它是這樣的:

private static Customer[] GetCustomers(IElasticClient elasticClient) 
{ 
    var customers = new List<Customer>(); 
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers()) 
          .Size(10000).SearchType(SearchType.Scan).Scroll("1m")); 

    do 
    { 
     var result = searchResult; 
     searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId); 
     customers.AddRange(searchResult.Documents); 
    } while (searchResult.IsValid && searchResult.Documents.Any()); 

    return customers.ToArray(); 
} 
-5

的最主要的原因,您收到此錯誤 - 這是becouse您使用的是一個錯誤的方式彈性搜索。 ES是一個搜索引擎。這對於獲取數據中的許多元素或許多頁面並不有效。也許你正試圖通過彈性搜索來操作所有數據,而不僅僅是搜索相關結果?這是不正確的。

所以,你應該使用它進行搜索。而且我認爲,沒有必要獲得超過10000個結果項目。例如,谷歌只返回前1000個結果。

0

如果您想要10000個以上的結果,那麼在所有數據節點中,內存使用率將非常高,因爲它必須在每個查詢請求中返回更多結果。那麼如果你有更多的數據和更多的碎片,那麼合併這些結果將是低效的。同時es緩存過濾器上下文,因此再次存儲更多內存。你必須嘗試和錯誤你正在採取多少。如果您在小窗口中收到很多請求,您應該執行多個查詢超過10k並將其自行合併到代碼中,如果您增加窗口大小,應該佔用更少的應用程序內存。

0

2)似乎沒有滾動API是我的選擇,但我不得不增加「index.max_result_window」。有人對這個有經驗麼?

- >您可以在索引模板中定義此值,es模板僅適用於新索引,因此您必須在創建模板後刪除舊索引或等待在elasticsearch中獲取新數據。

{ 「順序」:1, 「模板」: 「index_template *」, 「設置」:{ 「index.number_of_replicas」: 「0」, 「index.number_of_shards」: 「1」, 「index.max_result_window」:2147483647 },

9

正確的解決方案是使用滾動。
但是,如果你想擴展的結果10,000個以後的結果search回報,你可以很容易地Kibana做到這一點:

轉到Dev Tools,只是張貼下面您指數(your_index_name),specifing這將是新的最大結果窗口

enter image description here

PUT your_index_name/_settings 
{ 
    "max_result_window" : 500000 
} 

如果一切順利的話,你應該看到下面的成功響應:

{ 
    "acknowledged": true 
} 
+1

我嘗試了在elasticsearch代碼中執行此操作的方式(put_settings等)。並且達到了很多錯誤。這節省了我的時間!謝謝! – cpres