Случайный порядок и разбивка на страницы Elicsearch
В этой проблеме
это запрос функции для заказа с дополнительным семенем, позволяющий восстановить случайный порядок.
Мне нужно иметь возможность разбивать случайные упорядоченные результаты.
Как это можно сделать с помощью Elasticsearch 0.19.1?
Спасибо.
Ответы
Ответ 1
Вы можете сортировать с помощью хэш-функции уникального поля (например, 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
Это должно быть значительно быстрее, чем оба ответа выше, и поддерживает посев:
curl -XGET 'localhost:9200/_search' -d '{
"query": {
"function_score" : {
"query" : { "match_all": {} },
"random_score" : {}
}
}
}';
Смотрите: https://github.com/elasticsearch/elasticsearch/issues/1170
Ответ 3
Хорошее решение от имотов.
Вот что-то гораздо более простое, и вам не нужно полагаться на свойство документа:
{
"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 вашими правильными значениями.
Ответ 4
Я закончил тем, что решил немного отличаться от того, что предложил имотов. Поскольку у меня несколько клиентов, я не хотел реализовывать логику, связанную сольной строкой, на каждом из них.
У меня уже была randomized_key на модели. Я также не нуждался в том, чтобы порядок был случайным для каждого запроса, поэтому я сделал запланированную работу, чтобы обновлять рандомизированный ключ каждую ночь, а затем сортировать по этому полю в Elasticssearch.
Ответ 5
Ну, я смотрел на это, и все подходы выше казались немного "слишком сложными" для чего-то, что должно быть относительно простым. Поэтому я придумал альтернативу, которая работает отлично, без необходимости "умственного"
Сначала я выполняю запрос _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
- Вы также используете клиент PHP
Но вам НЕ НУЖНО делать это с помощью PHP, этот подход будет работать с любым примером.