随机顺序&分页Elasticsearch

时间:2012-03-20 23:17:46

标签: random pagination elasticsearch

this issue 是一个使用可选种子进行排序的功能请求,允许重新创建随机顺序。

我需要能够对随机排序的结果进行分页。 怎么可以用Elasticsearch 0.19.1来完成?

感谢。

5 个答案:

答案 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
  • 您还使用了PHP客户端

但是你不需要用PHP来做这个,这个方法适用于任何例子。