2012-03-20 17 views
24

this issue は、ランダム順序の再作成を可能にするオプションのシード付きの注文のための機能要求です。ランダム順序とページ番号Elasticsearch

ランダムな順序付けされた結果をページ付けできるようにする必要があります。 これはElasticsearch 0.19.1でどうすればできますか?

ありがとうございました。

答えて

30

一意のフィールド(たとえばid)とランダムな塩のハッシュ関数を使用してソートすることができます。結果はどうあるべきか、本当にランダムに応じて、同じくらい原始的な何かを行うことができます。

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "(doc['_id'].value + salt).hashCode()", 
     "type" : "number", 
     "params" : { 
      "salt" : "some_random_string" 
     }, 
     "order" : "asc" 
    } 
    } 
} 

または2番目の例では、より多くのランダムな結果を生成しますが、多少遅くなります

{ 
    "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" 
    } 
    } 
} 

のように洗練された何か。

この手法を使用するには、_idというフィールドを格納する必要があります。そうでない場合、クエリはNullPointerExceptionで失敗します。

+0

文字列をクライアントに保存しますか?例えば、クッキーの中で?ユーザーがページ2を呼び出すと、同じ注文が保存されるようになりますか? – Yeggeps

+0

ソルト文字列を生成し、ユーザーのセッションを維持するレイヤーに格納する必要があります。ユーザーのクエリまたは現在表示されているページ番号を格納する場所と同じ場所にすることができます。クッキーにすることもできます。 – imotov

3

私は、imotovが示唆したものと少し違って解決しました。私は複数のクライアントを持っているので、私は塩ストリングを取り囲むロジックをそれらのすべてに実装したくありませんでした。

私はすでにモデルにrandomized_keyを持っていました。私はまた、毎回ランダムな注文をする必要はありませんでしたので、私は毎晩ランダム化されたキーを更新し、Elasticssearchのそのフィールドでソートしてスケジュールされた仕事をしました。

18

imotovからの良い解決策。

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "Math.random() * (myMax - myMin) + myMin", 
     "type" : "number", 
     "params" : {}, 
     "order" : "asc" 
    } 
    } 
} 

:あなたのようなものになるだろう範囲を設定したい場合は

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "Math.random()", 
     "type" : "number", 
     "params" : {}, 
     "order" : "asc" 
    } 
    } 
} 

:ここ

は、はるかに簡単で、あなたはドキュメントプロパティに依存する必要はありませんものです最大値と最小値を適切な値に置き換えます。

+5

これは良い一般的な解決策です。しかし、元来の質問は、「無作為注文のレクリエーションを可能にするオプションの種」を求めていた。それだけで複雑さが増しています。 – imotov

+0

はい、あなたは完全に正しいです。私のソリューションは、タイトル「ランダム注文とページング弾性検索」にさらに適しています。 Yeggepsニーズには完全に不十分です。 – DavidGOrtega

+3

基本的なランダムな順序付けのための優れた答え – Eva

50

これはかなり速く、上記の両方の答えよりもや播種をサポートする必要があります

curl -XGET 'localhost:9200/_search' -d '{ 
    "query": { 
    "function_score" : { 
     "query" : { "match_all": {} }, 
     "random_score" : {} 
    } 
    } 
}'; 

参照:https://github.com/elasticsearch/elasticsearch/issues/1170

+1

ご協力ありがとうございます。私は、例のクエリを更新すると、random_scoreがシードをサポートすることが明らかになります。 –

+0

フィルタを使用すると機能しません。 –

0

さて、私はこれをやって見ていたし、上記のすべてのアプローチは少し「複雑すぎるように見えました比較的単純なものでなければなりません。だから、私は、「スタート」およびランド(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クライアントを使用しているしかし、あなたがこれを行う必要がありいけないPHP

  • を実行していますPHPでは、このアプローチはどんな例でも動作します。