Duda sobre rendimiento de filtros en agregaciones

Hola! Tengo una duda que puede servir a mucha gente (creo). Que diferencia hay entre filtrar a nivel de query o usando una aggregation filter? Me explico un poco mejor:
Que es mejor (a nivel de rendimiento y usos de recursos/RAM):

GET mi_indice/_search
{
  "size": 0,
  "aggs": {
    "filter_date": {
      "filter": {"range": { "price": { "gte": "1000" }}},
      "aggs": {
        "cars": {
          "terms": {
            "field": "car",
            "size": 10
          }
        }
      }
    }
  }
}

o esto:

GET mi_indice/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter":  {"range": { "price": { "gte": 1000 }}}
    }
  }, 
  "aggs": {
    "cars": {
      "terms": {
        "field": "car",
        "size": 10
      }
    }
  }
}

Lo digo, porque en la versión 2.x de ES aunque yo creía que la agregación se hacía sobre el set de resultados, en realidad lo que deduje que se hacía era hacer la agregación y la query y luego cruzar los resultados. Esto lo deduje (igual estoy equivocado) porque hacía una agregación con size:0 (que ahora ya no se puede) y tumbaba el nodo, aunque en la query tenía un filtro que sólo me retornaba 1 elemento, con lo que la agg sólo debería tener 1 elemento.

Muchas gracias!!!

Hola Guillermo,

Es una buena pregunta. En versiones mayores (mayor versions) de Elasticsearch fue cambiando un poco como funciona el cache de los filtros, aunque te recomiendo siempre utilizar los filtros en la parte de la búsqueda. Los filtros genericos que se utilizan en las aggregaciones, generalmente son mas lentos.

Por otro lado, cuando se hacen filtros de fechas, si se hacen busquedas en varios indices, en versiones 6.0 es mucho mas performante ponerlo en la parte de la query mas que en la de las aggregaciones.

Por otro lado, siempre recomiendo testear esto para validarlo, pero la segunda opcion deberia de ser mejor.

Lo de la agregacion de size:0 lo que hacia era retornar TODO, pero ahora hay un limite y ademas eso siempre fue una mala idea, por eso no es bueno hacerlo.

Saludos!

--Gabriel

Muchas gracias Gabriel. En mi caso no prima tanto la velocidad (no me viene de unos segundos) como el poder hacer agregaciones de todos los datos (de ahí a usar size:0). Ahora con las particiones de las terms aggregations creo tener este tema resuelto. Lo que me interesa más que la velocidad, es no quedarme sin memoria y provocar caídas en los nodos cuando "recorro" todas las agregaciones.
Seguiré tu consejo y dejaré los filtros en la query.

Gracias de nuevo.

Gracias por la respuesta.

Por lo que entiendo si lo que te preocupa es la memoria, lo mejor es ver lo siguiente: https://www.elastic.co/guide/en/elasticsearch/reference/6.2/circuit-breaker.html. Los Circuit Breakers son los que cortaran una operación si por algún motivo se excede la memoria que tiene asignada el nodo.

También para los buckets, es importante esto: https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket.html.

The maximum number of buckets allowed in a single response is limited by a dynamic cluster setting named search.max_buckets. It defaults to 10,000, requests that try to return more than the limit will fail with an exception.

Básicamente hay un máximo de 10000 buckets a retornar, que puedes modificarlo a menos si quieres. Esto limita también la capacidad de un nodo en colapsar los resultados pero no retornar mas de n buckets y no exceder la memoria.

Hola de nuevo. Si que conocía el CircuitBreaker, pero para ser honestos no lo termino de comprender, pues aún teniéndolo configurado, las consultas que yo hacía hacían que el nodo fallara.
Revisaré la configuración ahora que voy a migrar a la 6
Supongo que aunque el límite esté en los 10000 buckets, si hago un cálculo de la cardinalidad del campo que quiero agregar y uso las particiones podré iterar por todas las agregaciones? Creo que eso me solventaría muchos de mis problemas. Como ya te dije, para mí lo más importante no es la velocidad (que también) si no el que todos los datos sean consistentes.

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions

Un saludo!

Estimo que si.

La idea de partitions es partir el problema en pedazos. Pero bueno, yo con mi experiencia te digo que lo pruebes ahi veremos la realidad.

Saludos!

--Gabriel

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.