問題:10,000件を超える結果を取得する場合、GET/searchクエリでの検索によるエラスティック検索が行われます。
GET hostname:port /myIndex/_search {
"size": 10000,
"query": {
"term": { "field": "myField" }
}
}
私はそれを知っているサイズオプションを使用しています:
index.max_result_window = 100000
しかし、クエリのサイズが650,000ドキュメント以上の場合、1つのGETですべての結果を取得するにはどうすればよいですか?
SCROLL、FROM-TO、およびPAGINATION APIについて読んでいますが、それらはすべて10Kを超えることはありません。
これは、私が使用しているElasticsearch Forumの例です。
GET /_search?scroll=1m
GET検索クエリのすべてのドキュメントを取得できる例を提供できますか?
どうもありがとうございました。
スクロールは、多数のドキュメントを取得する場合の方法です。10000のデフォルトの制限を超える可能性があるという意味で高くなっています。
最初のリクエストでは、作成するクエリとscroll
パラメータを期間 検索コンテキストがタイムアウトする前 (以下の例では1分)で指定する必要があります
POST /index/type/_search?scroll=1m
{
"size": 1000,
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
その最初の呼び出しへの応答では、_scroll_id
2番目の呼び出しを行うために使用する必要があります。
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
その後の各応答では、新しい_scroll_id
必要なドキュメントの量を取得するまで、次の呼び出しに使用する必要があります。
そのため、擬似コードでは次のようになります。
# first request
response = request('POST /index/type/_search?scroll=1m')
docs = [ response.hits ]
scroll_id = response._scroll_id
# subsequent requests
while (true) {
response = request('POST /_search/scroll', scroll_id)
docs.Push(response.hits)
scroll_id = response._scroll_id
}
elascticsearch を使用したnodeJSスクロールの例:
const elasticsearch = require('elasticsearch');
const elasticSearchClient = new elasticsearch.Client({ Host: 'esURL' });
async function getAllData(query) {
const result = await elasticSearchClient.search({
index: '*',
scroll: '10m',
size: 10000,
body: query,
});
const retriever = async ({
data,
total,
scrollId,
}) => {
if (data.length >= total) {
return data;
}
const result = await elasticSearchClient.scroll({
scroll: '10m',
scroll_id: scrollId,
});
data = [...data, ...result.hits.hits];
return retriever({
total,
scrollId: result._scroll_id,
data,
});
};
return retriever({
total: result.hits.total,
scrollId: result._scroll_id,
data: result.hits.hits,
});
}
別のオプションは search_after タグです。ソートメカニズムを使用すると、最初のリターンで最後の要素を保存して、その最後の要素の後に来る結果を要求できます。
GET Twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [1463538857, "654323"],
"sort": [
{"date": "asc"},
{"_id": "desc"}
]
}
私のために働いた。しかし、今まで10.000以上のドキュメントを取得するのは本当に簡単ではありません。
どうぞ:
GET /_search
{
"size": "10000",
"query": {
"match_all": {"boost" : "1.0" }
}
}
ただし、データの使用量とオーバーヘッドが増加する可能性があるため、大量のドキュメントを一度に取得するこのアプローチはほとんど避ける必要があります。
これを行うより良い方法を提案できます。 10,000件以上のレコードを取得しようとしていると思います。以下の方法を試してください。数百万件のレコードも取得できます。
クライアントを定義します。
_client = Elasticsearch(['http://localhost:9200'])
_
search = Search(using=client)
ヒットの総数を確認してください。
_results = search.execute()
results.hits.total
_
s = Search(using=client)
クエリを書き留めます。
_s = s.query(..write your query here...)
_
スキャンを使用してデータをデータフレームにダンプします。スキャンは、たとえ数十億単位であっても、すべてのデータをデータフレームにダンプするため、注意が必要です。
_results_df = pd.DataFrame((d.to_dict() for d in s.scan()))
_
データフレームをご覧ください。
_results_df
_
検索機能でエラーが発生した場合は、以下を実行してください。
_from elasticsearch_dsl import Search
_
search_after documentation を見てください
Rubyのハッシュとしてのクエリの例:
query = {
size: query_size,
query: {
multi_match: {
query: "black",
fields: [ "description", "title", "information", "params" ]
}
},
search_after: [after],
sort: [ {id: "asc"} ]
}
結果が10000を超える場合、残りを取得する唯一の方法は、各クエリが10000未満の結果を返すように、クエリをより厳密なフィルターを使用して複数のより洗練されたクエリに分割することです。そして、クエリ結果を組み合わせて、完全なターゲット結果セットを取得します。
10000の結果に対するこの制限は、ElasticSearchインデックスによってサポートされるWebサービスに適用され、それを回避する方法はありません。ElasticSearchを使用せずにWebサービスを再実装する必要があります。