この問題 には、ランダムな順序の再作成を可能にするオプションのシードを使用した注文の機能リクエストがあります。
ランダムに並べられた結果をページ分割できるようにする必要があります。 Elasticsearch 0.19.1でこれをどのように行うことができますか?
ありがとう。
一意のフィールド(idなど)のハッシュ関数とランダムなソルトを使用してソートできます。結果の真のランダム度に応じて、次のような原始的なことを実行できます。
{
"query" : { "query_string" : {"query" : "*:*"} },
"sort" : {
"_script" : {
"script" : "(doc['_id'].value + salt).hashCode()",
"type" : "number",
"params" : {
"salt" : "some_random_string"
},
"order" : "asc"
}
}
}
または洗練されたもの
{
"query" : { "query_string" : {"query" : "*:*"} },
"sort" : {
"_script" : {
"script" : "org.elasticsearch.common.Digest.md5Hex(doc['_id'].value + salt)",
"type" : "string",
"params" : {
"salt" : "some_random_string"
},
"order" : "asc"
}
}
}
2番目の例では、よりランダムな結果が生成されますが、多少遅くなります。
このアプローチでフィールド_id
を保存する必要があります。そうでない場合、クエリはNullPointerException
で失敗します。
これは上記の両方の答えよりもかなり速く、シードをサポートします:
curl -XGET 'localhost:9200/_search' -d '{
"query": {
"function_score" : {
"query" : { "match_all": {} },
"random_score" : {}
}
}
}';
参照: https://github.com/elasticsearch/elasticsearch/issues/117
Imotovからの良い解決策。
これははるかに単純なものであり、ドキュメントプロパティに依存する必要はありません。
{
"query" : { "query_string" : {"query" : "*:*"} },
"sort" : {
"_script" : {
"script" : "Math.random()",
"type" : "number",
"params" : {},
"order" : "asc"
}
}
}
次のような範囲を設定する場合:
{
"query" : { "query_string" : {"query" : "*:*"} },
"sort" : {
"_script" : {
"script" : "Math.random() * (myMax - myMin) + myMin",
"type" : "number",
"params" : {},
"order" : "asc"
}
}
}
maxとminを適切な値に置き換えます。
私はimotovが提案したものとは少し異なる方法で解決しました。クライアントが複数あるので、すべてのクライアントにソルト文字列を取り巻くロジックを実装したくありませんでした。
モデルにはすでにrandomized_keyがありました。また、すべてのリクエストで順序がランダムである必要はなかったので、ランダムなキーを毎晩更新するようにスケジュールされたジョブを作成し、Elasticssearchのそのフィールドでソートしました。
ええと、私はこれを行うことを検討していましたが、上記のすべてのアプローチは、比較的単純なものに対しては少し「複雑すぎる」ように見えました。だから私は「精神的に行く」必要がなくても完璧に機能する代替案を思いついた
最初に_countクエリを実行してから、それを "Start"およびRand(0、$ count)と組み合わせます
例えば.
JSONArray = array of json to send to ElasticSearch
$total_results = $ElasticSearchClient->count(JSONArray)
$start = Rand(0, $total_results)
JSONArray['body']['from'] = $start;
$ElasticSearchClient->search(JSONArray);
上記の例の前提:
しかし、PHPでこれを行う必要はありません。このアプローチはどのような例でも機能します。