Random order & pagination Elasticsearch
This should be considerably faster than both answers above and supports seeding:
curl -XGET 'localhost:9200/_search' -d '{ "query": { "function_score" : { "query" : { "match_all": {} }, "random_score" : {} } }}';
See: https://github.com/elasticsearch/elasticsearch/issues/1170
You can sort using a hash function of a unique field (for example id) and a random salt. Depending on how truly random the results should be, you can do something as primitive as:
{ "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "(doc['_id'].value + salt).hashCode()", "type" : "number", "params" : { "salt" : "some_random_string" }, "order" : "asc" } }}
or something as sophisticated as
{ "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" } }}
The second example will produce more random results but will be somewhat slower.
For this approach to work the field _id
has to be stored. Otherwise, the query will fail with NullPointerException
.
Good solution from imotov.
Here is something much more simple and you don't need to rely in a document property:
{ "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "Math.random()", "type" : "number", "params" : {}, "order" : "asc" } }}
if you want to set a range that would be something like:
{ "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "Math.random() * (myMax - myMin) + myMin", "type" : "number", "params" : {}, "order" : "asc" } }}
replacing the max and min with your proper values.