这应该比上面的两个答案都要快得多,并支持种子:
curl -XGET 'localhost:9200/_search' -d '{
"query": {
"function_score" : {
"query" : { "match_all": {} },
"random_score" : {}
}
}
}';
请参阅:https://github.com/elasticsearch/elasticsearch/issues/1170
{
"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
异常。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"
}
}
}
将最大值和最小值替换为适当的值。
我最终解决了这个问题,但方法略有不同于imotov的建议。因为我有多个客户端,我不想在每个客户端上都实现盐字符串周围的逻辑。
我已经在模型上有一个随机化密钥。我也不需要每次请求时都是随机顺序,所以我创建了一个定时作业,在晚上更新随机密钥,然后按该字段在Elasticsearch中进行排序。
新格式:
{
"sort": {
"_script": {
"type": "number",
"script": {
"source": "Math.random()",
"lang": "painless"
},
"order": "asc"
}
}
}
嗯,我一直在考虑这个问题,上面的所有方法似乎都有点“太复杂”了,对于应该相对简单的事情来说。所以我想出了一个替代方案,完全可以正常工作,而不需要“发疯”。
我首先执行一个_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来实现这个方法,该方法适用于任何示例。
"boost_mode": "replace",
,请参见 https://dev59.com/D1sX5IYBdhLWcg3wLdCJ#48338880。 - bato3