Подтвердить что ты не робот

Случайный порядок и разбивка на страницы Elicsearch

В этой проблеме это запрос функции для заказа с дополнительным семенем, позволяющий восстановить случайный порядок.

Мне нужно иметь возможность разбивать случайные упорядоченные результаты. Как это можно сделать с помощью Elasticsearch 0.19.1?

Спасибо.

4b9b3361

Ответ 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, этот подход будет работать с любым примером.