Elasticsearch 2.1:結果ウィンドウが大きすぎます(index.max_result_window)


86

Elasticsearch 2.1から情報を取得し、ユーザーが結果をページングできるようにします。ユーザーが高いページ番号を要求すると、次のエラーメッセージが表示されます。

結果ウィンドウが大きすぎます。+サイズは[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)結果10000-10020の「通常の」検索要求を実行する代わりに、スクロールAPIを使用して結果10020までスクロールアップした場合(および10000未満のすべてを無視した場合)、メモリ消費量は実際に少なくなりますか(その場合は理由はありますか)?

2)スクロールAPIは私にとってオプションではないようですが、「index.max_result_window」を増やす必要があるようです。誰かがこれについて何か経験がありますか?

3)私の問題を解決する他のオプションはありますか?

回答:


79

深いページ付けが必要な場合、考えられる解決策の1つは、値を増やすことですmax_result_windowcurlシェルコマンドラインからこれを行うために使用できます。

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

〜100kの値では、メモリ使用量の増加に気づきませんでした。


同じエラーが発生します'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.')4719ページ(10ページごとの結果)があると表示されました。そして私はあなたの提案がうまくいくと思います。
dotlash 2016

1
これは、500000未満の少量のドキュメントに適したソリューションです
Ezzat 2017年

2
ES v2.2.0を使用していますが、{ "max_result_window" : 500000 }これを機能させるにはペイロードをに変更する必要がありました。カールコマンドがなったので-curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Parin Porecha

3
新しいバージョンのelasticsearchでこのコマンドを使用してヘッダーエラーが発生した場合は、ヘッダーも渡す必要があります。curl-XPUT " localhost:9200 / my_index / _settings " -H "Content-Type:application / json" -d '{ "index":{"max_result_window":50000}} '
Satys 2018

32

正しい解決策は、スクロールを使用することです。
ただし、結果のsearch戻り値を10,000件を超えて拡張する場合は、Kibanaを使用して簡単に行うことができます。

Dev Tools次の項目に移動して、インデックス(your_index_name)に投稿し、新しい最大結果ウィンドウを指定します。

ここに画像の説明を入力してください

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

すべてがうまくいけば、次の成功応答が表示されます。

{
  "acknowledged": true
}

1
Elasticsearchコード(put_settingsなど)でこれを行う方法に従ってみましたが、多くのエラーが発生しました。これで時間を節約できます!ありがとうございました!
cpres 2017

24

エラスティックドキュメントの次のページでは、ディープページングについて説明しています。

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、メモリ、および帯域幅を使用して、ソートプロセスが実際に非常に重くなる可能性があります。このため、ディープページングは​​強くお勧めします。


1
だからここでは、深いページ付けを放棄する必要がありますよね?基本的に、1人のビューアで4000ページをページングする意味はありません。たとえば、グーグル検索では、結果を確認するために8ページまたは9ページにスクロールすることはほとんどありません。通常、Googleが提供する上位3〜5ページのみを処理します。
dotlash 2016

2
深いページ付けが必要な場合にスクロールAPIを使用できますか?
Abhi.G 2016年

3
しかし、ソート機能を有効にすると、eコマースサイトで言いましょう。ユーザーが最も高い価格のアイテムを見たいとき。最高価格で並べ替えた場合と最低ページで並べ替えた場合の結果は異なりますが、最後のページに移動しますか?アクセスできる結果の数が制限されているためです。これに対する回避策はありますか?
MR Murazza 2017年

3

Scroll APIを使用して、10000を超える結果を取得します。

ElasticSearch NESTAPIのスクロール例

私はそれをこのように使用しました:

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();
}

0

10000を超える結果が必要な場合は、すべてのデータノードで、各クエリリクエストでより多くの結果を返す必要があるため、メモリ使用量が非常に高くなります。次に、より多くのデータとより多くのシャードがある場合、それらの結果をマージすることは非効率的です。また、esはフィルターコンテキストをキャッシュするため、メモリが増えます。どれだけ正確に取っているかを試行錯誤する必要があります。小さなウィンドウで多くのリクエストを受け取っている場合は、10kを超える複数のクエリを実行し、コード内でそれを自分でマージする必要があります。これにより、ウィンドウサイズを大きくした場合よりも、アプリケーションのメモリが少なくて済みます。


0

2)スクロールAPIは私にとってオプションではないようですが、「index.max_result_window」を増やす必要があるようです。誰かがこれについて何か経験がありますか?

->この値はインデックステンプレートで定義できます。esテンプレートは新しいインデックスにのみ適用されるため、テンプレートの作成後に古いインデックスを削除するか、elasticsearchに新しいデータが取り込まれるのを待つ必要があります。

{"order":1、 "template": "index_template *"、 "settings":{"index.number_of_replicas": "0"、 "index.number_of_shards": "1"、 "index.max_result_window":2147483647}、


0

私の場合、from&sizeプレフィックスを使用して結果をクエリに縮小すると、すべての結果が必要になるわけではないため、エラーが削除されるようです。

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.