Elasticsearch 2.1: la ventana de resultados es demasiado grande (index.max_result_window)

86

Recuperamos información de Elasticsearch 2.1 y permitimos que el usuario revise los resultados. Cuando el usuario solicita un número de página alto, aparece el siguiente mensaje de error:

La ventana de resultado es demasiado grande, desde + el tamaño debe ser menor o igual a: [10000] pero era [10020]. Consulte la API de desplazamiento para obtener una forma más eficiente de solicitar grandes conjuntos de datos. Este límite se puede establecer cambiando el parámetro de nivel de índice [index.max_result_window]

El documento elástico dice que esto se debe al alto consumo de memoria y al uso de la API de desplazamiento:

Los valores más altos pueden consumir porciones significativas de memoria de pila por búsqueda y por fragmento que ejecuta la búsqueda. Es más seguro dejar este valor, ya que es un uso de la API de desplazamiento para cualquier desplazamiento profundo https://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

El caso es que no quiero recuperar grandes conjuntos de datos. Solo quiero recuperar una porción del conjunto de datos que está muy arriba en el conjunto de resultados. También el documento de desplazamiento dice:

El desplazamiento no está diseñado para solicitudes de usuarios en tiempo real https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

Esto me deja con algunas preguntas:

1) ¿El consumo de memoria sería realmente menor (si es así, por qué) si uso la API de desplazamiento para desplazarme hasta el resultado 10020 (y descarto todo lo que esté por debajo de 10000) en lugar de realizar una solicitud de búsqueda "normal" para el resultado 10000-10020?

2) No parece que la API de desplazamiento sea una opción para mí, pero tengo que aumentar "index.max_result_window". ¿Alguien tiene alguna experiencia con esto?

3) ¿Existen otras opciones para solucionar mi problema?

Ronald
fuente

Respuestas:

79

Si necesita una paginación profunda, una posible solución es aumentar el valor max_result_window. Puede usar curlpara hacer esto desde la línea de comandos de su shell:

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

No noté un mayor uso de memoria, para valores de ~ 100k.

Andrey Morozov
fuente
Tengo el mismo error 'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.')Dijo que tiene 4719 páginas (cada página 10 resultados). y creo que tu sugerencia funciona.
Dotslash
1
Esta es una buena solución para pequeñas cantidades de documentos de menos de 500000
Ezzat
2
Estoy usando ES v2.2.0 y tuve que cambiar la carga útil { "max_result_window" : 500000 }para que esto funcione. Entonces el comando curl se convirtió en -curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Parin Porecha
3
para aquellos que obtienen un error de encabezado con este comando para la versión más reciente de elasticsearch, también deben pasar el encabezado, curl -XPUT " localhost: 9200 / my_index / _settings " -H "Content-Type: application / json" -d '{ "index": {"max_result_window": 50000}} '
Sábado
32

La solución correcta sería utilizar el desplazamiento.
Sin embargo, si desea extender los searchretornos de resultados más allá de 10,000 resultados, puede hacerlo fácilmente con Kibana:

Vaya a Dev Toolsy publique lo siguiente en su índice (your_index_name), especificando cuál sería la nueva ventana de resultado máximo

ingrese la descripción de la imagen aquí

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

Si todo va bien, debería ver la siguiente respuesta de éxito:

{
  "acknowledged": true
}
Guy Dubrovski
fuente
1
Intenté seguir la forma de hacer esto en el código de elasticsearch (put_settings, etc.) y encontré muchos errores. ¡Esto me ahorra horas! ¡Gracias!
cpres
24

Las siguientes páginas de la documentación elástica hablan sobre la paginación profunda:

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

Dependiendo del tamaño de sus documentos, la cantidad de fragmentos y el hardware que esté utilizando, la paginación de 10,000 a 50,000 resultados (1,000 a 5,000 páginas) de profundidad debería ser perfectamente factible. Pero con valores de from suficientemente grandes, el proceso de clasificación puede llegar a ser muy pesado, utilizando grandes cantidades de CPU, memoria y ancho de banda. Por esta razón, le recomendamos encarecidamente que no utilice la paginación profunda.

Ronald
fuente
1
Entonces aquí, deberíamos abandonar la paginación profunda, ¿verdad? Básicamente, no tiene sentido paginar 4000 páginas para un solo espectador. Digamos, búsqueda de Google, apenas nos desplazamos a la página 8 o 9 para comprobar los resultados. Por lo general, solo nos ocupamos de las 3-5 páginas principales que nos brinda Google.
dotslash
2
¿Podemos usar la API de desplazamiento en caso de que necesitemos una paginación profunda?
Abhi.G
3
Pero cuando habilitamos la función de clasificación, digamos en un sitio de comercio electrónico. cuando el usuario quiere ver los artículos con el precio más alto. El resultado será diferente cuando clasifiquemos por precio más alto en comparación con cuando clasificamos por página más baja pero vamos a la última página, ¿verdad? ya que limitamos el número de resultados que se pueden acceder. alguna solución para esto?
MR Murazza
3

Utilice la API de desplazamiento para obtener más de 10000 resultados.

Ejemplo de desplazamiento en ElasticSearch NEST API

Lo he usado así:

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}
Morten Holmgaard
fuente
0

Si desea más de 10000 resultados, en todos los nodos de datos el uso de memoria será muy alto porque tiene que devolver más resultados en cada solicitud de consulta. Entonces, si tiene más datos y más fragmentos, fusionar esos resultados será ineficaz. También almacena en caché el contexto del filtro, por lo tanto, nuevamente, más memoria. Tienes que probar y equivocarte cuánto estás tomando exactamente. Si recibe muchas solicitudes en una ventana pequeña, debe hacer varias consultas por más de 10k y fusionarlas usted mismo en el código, lo que se supone que ocupará menos memoria de la aplicación que si aumenta el tamaño de la ventana.

Amritendu
fuente
0

2) No parece que la API de desplazamiento sea una opción para mí, pero tengo que aumentar "index.max_result_window". ¿Alguien tiene alguna experiencia con esto?

-> Puede definir este valor en las plantillas de índice, la plantilla es aplicable solo para los índices nuevos, por lo que debe eliminar los índices antiguos después de crear la plantilla o esperar a que se ingieran nuevos datos en elasticsearch.

{"order": 1, "template": "index_template *", "settings": {"index.number_of_replicas": "0", "index.number_of_shards": "1", "index.max_result_window": 2147483647},

Sindhu
fuente
0

En mi caso, parece que reducir los resultados a través de los prefijos from & size a la consulta eliminará el error ya que no necesitamos todos los resultados:

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
FlimFlam Vir
fuente