Случайный порядок и нумерация страниц - PullRequest
25 голосов
/ 21 марта 2012

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

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

Спасибо.

Ответы [ 5 ]

56 голосов
/ 27 декабря 2013

Это должно быть значительно быстрее, чем оба ответа выше, и поддерживает посев:

curl -XGET 'localhost:9200/_search' -d '{
  "query": {
    "function_score" : {
      "query" : { "match_all": {} },
      "random_score" : {}
    }
  }
}';

См .: https://github.com/elasticsearch/elasticsearch/issues/1170

32 голосов
/ 21 марта 2012

Вы можете сортировать, используя хэш-функцию уникального поля (например, 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.

21 голосов
/ 26 сентября 2012

Хорошее решение от 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"
    }
  }
}

с заменой макс и мин на ваши правильные значения.

3 голосов
/ 21 марта 2012

Я решил, что это немного отличается от того, что предложил Имотов. Поскольку у меня несколько клиентов, я не хотел реализовывать логику, заключенную в солт-строку, на каждом из них.

У меня уже был случайный ключ на модели. Мне также не нужно было, чтобы порядок был случайным для каждого запроса, поэтому я выполнил запланированное задание для обновления рандомизированного ключа каждую ночь, а затем сортировал его по этому полю в Elasticssearch.

0 голосов
/ 21 марта 2014

Ну, я смотрел на это, и все вышеперечисленные подходы казались немного "слишком сложными" для чего-то, что должно быть относительно простым.Итак, я нашел альтернативу, которая прекрасно работает без необходимости «сходить с ума»

Сначала я выполняю запрос _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, подход подойдет для любого примера.

...