2012-03-20 96 views

回答

30

您可以使用唯一字段(例如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" 
    } 
    } 
} 

第二個例子將產生更多的隨機的結果,但會略慢一些。

對於這種工作方法,必須存儲該字段_id。否則,查詢將失敗,並顯示NullPointerException

+0

我會將字符串存儲在客戶端上嗎?例如在一個cookie?因此,當用戶呼叫第2頁時,相同的順序被保存下來了? – Yeggeps 2012-03-21 13:42:42

+0

應該生成salt字符串並存儲在維護用戶會話的圖層上。它可以是您存儲用戶查詢或當前顯示的頁碼的相同位置。它也可以是cookie。 – imotov 2012-03-21 13:58:33

3

我最終解決了它與imotov建議的稍有不同。由於我有多個客戶端,我不想在每個客戶端上實現圍繞鹽串的邏輯。

我已經在模型上有一個randomized_key。我也不需要爲每個請求隨機的命令,所以我做了一個預定的工作,每晚更新隨機密鑰,然後在Elasticssearch中按照該字段進行排序。

18

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

用適當的值代替最大值和最小值。

+5

這是一個很好的通用解決方案。然而,最初的問題是要求「可選的種子允許娛樂隨機順序」。這就是所有複雜性來自的地方。 – imotov 2012-09-26 16:49:21

+0

是的,你完全正確。我的解決方案更適合標題「隨機排序和分頁Elasticsearch」。完全不能滿足Yegegeps的需求。 – DavidGOrtega 2012-09-26 18:30:43

+3

基本的隨機排序優秀的答案,謝謝 – Eva 2013-04-18 05:10:55

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支持種子播種。 – 2017-02-21 10:48:51

+0

如果您使用過濾器,則不起作用。 – 2017-05-23 13:08:19

0

嗯,我一直在尋找這樣做的,上面所有的方法似乎有點「太複雜「對於那些應該相對簡單的事情來說。所以,我想出了好完美的作品,而不需要「走出心理」

我先執行_count查詢然後用「開始」和蘭特(0,$計數)

例如結合它的替代

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,這種方法可以用於任何示例。