Orden aleatorio y paginación Elasticsearch

En este número se trata de una solicitud de función para realizar un pedido con una semilla opcional que permite la recreación de orden aleatorio.

Necesito poder paginar resultados ordenados al azar. ¿Cómo podría hacerse esto con Elasticsearch 0.19.1?

Gracias.

Puede ordenar utilizando una función hash de un campo único (por ejemplo, id) y una sal aleatoria. Dependiendo de qué tan aleatorios sean los resultados, puedes hacer algo tan primitivo como:

{ "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "(doc['_id'].value + salt).hashCode()", "type" : "number", "params" : { "salt" : "some_random_string" }, "order" : "asc" } } } 

o algo tan sofisticado como

 { "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" } } } 

El segundo ejemplo producirá resultados más aleatorios pero será algo más lento.

Para que este enfoque funcione, el campo _id debe almacenarse. De lo contrario, la consulta fallará con NullPointerException .

Esto debería ser considerablemente más rápido que las dos respuestas anteriores y es compatible con la siembra:

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

Ver: https://github.com/elasticsearch/elasticsearch/issues/1170

Buena solución de imotov.

Aquí hay algo mucho más simple y no necesita confiar en una propiedad del documento:

 { "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "Math.random()", "type" : "number", "params" : {}, "order" : "asc" } } } 

si quieres establecer un rango que sería algo así como:

 { "query" : { "query_string" : {"query" : "*:*"} }, "sort" : { "_script" : { "script" : "Math.random() * (myMax - myMin) + myMin", "type" : "number", "params" : {}, "order" : "asc" } } } 

reemplazando el máximo y el mínimo con sus valores correctos.

Terminé resolviéndolo ligeramente diferente de lo que sugirió imotov. Como tengo varios clientes, no quería implementar la lógica que rodea a la cadena de sal en cada uno de ellos.

Ya tenía una clave_aleatoria en el modelo. Tampoco necesitaba que la orden fuera aleatoria para cada solicitud, así que hice un trabajo progtwigdo para actualizar la clave aleatorizada todas las noches y luego ordené por ese campo en Elasticssearch.

Bueno, estaba considerando hacer esto y todos los enfoques anteriores parecían un poco “demasiado complicados” para algo que debería ser relativamente simple. Así que se me ocurrió una alternativa que funciona perfectamente bien sin la necesidad de “ir mentalmente”

Realizo primero una consulta _count y luego la combino con “Inicio” y rand (0, $ count)

p.ej

 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); 

Supuestos para el ejemplo anterior:

  • Estás ejecutando PHP
  • También está utilizando el Cliente PHP

Pero no NECESITA hacer esto con PHP, el enfoque funcionaría con cualquier ejemplo.