答案 0 :(得分:56)
这应该比上述两个答案都快得多,并支持播种:
curl -XGET 'localhost:9200/_search' -d '{
"query": {
"function_score" : {
"query" : { "match_all": {} },
"random_score" : {}
}
}
}';
请参阅:https://github.com/elasticsearch/elasticsearch/issues/1170
答案 1 :(得分:32)
您可以使用唯一字段(例如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
。
答案 2 :(得分:21)
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。
答案 3 :(得分:3)
我最终解决的问题与伊莫托夫的建议略有不同。因为我有多个客户端,所以我不想在每个客户端上实现围绕salt字符串的逻辑。
我已经在模型上有一个randomized_key。我也不需要每个请求的随机顺序,所以我做了一个预定的工作,每晚更新随机密钥,然后按照Elasticssearch中的那个字段进行排序。
答案 4 :(得分:0)
好吧,我正在考虑这样做,上面的所有方法看起来都有点太复杂了#34;对于应该相对简单的事情。因此,我提出了一种非常有效的替代方案,而不需要"进入心理"
我首先执行_count查询,然后将其与" Start"和兰特(0,$ count)
e.g。
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来做这个,这个方法适用于任何例子。