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)スクロールAPIを使用して、結果10000-10020に対して「通常の」検索要求を行うのではなく、結果10020までスクロールする(そして10000未満のすべてを無視する)場合、メモリ消費は実際に低くなりますか?
2)スクロールAPIは私にとってオプションではないようですが、 "index.max_result_window"を増やす必要があります。誰もこれを経験したことがありますか?
3)問題を解決する他のオプションはありますか?
エラスティックドキュメントの次のページでは、ディープページングについて説明しています。
https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.htmlhttps://www.elastic.co/guide/en/elasticsearch/ guide/current/_fetch_phase.html
ドキュメントのサイズ、シャードの数、および使用しているハードウェアに応じて、10,000〜50,000の結果(1,000〜5,000ページ)の深さのページングが完全に実行可能になります。しかし、値から大きくなると、膨大な量のCPU、メモリ、帯域幅を使用して、ソートプロセスが実際に非常に重くなる可能性があります。このため、ディープページングを強くお勧めします。
大きな深いページネーションが必要な場合、ソリューションの1つのバリエーションは値max_result_windowを増やすことだけだと思います
curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "index" : { "max_result_window" : 500000 } }'
メモリ使用量の増加、私は〜100kの値が見つかりません
Scroll APIを使用して、10000を超える結果を取得します。
私はこれを次のように使用しました:
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();
}
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}、
10000を超える結果が必要な場合、すべてのデータノードで、各クエリ要求でより多くの結果を返す必要があるため、メモリ使用量が非常に高くなります。その後、より多くのデータとより多くのシャードがある場合、それらの結果をマージすることは非効率的です。また、esはフィルターコンテキストをキャッシュするため、メモリが増えます。どれだけ正確に服用しているかを試行錯誤する必要があります。小さなウィンドウで多くのリクエストを取得している場合は、10k以上の複数のクエリを実行し、コードでそれを自分でマージする必要があります。