[Guia Completo Elastic Stack] — Capítulo 8.2 — Agregações avançadas e não convencionais — Bucket Selector

Felipe Queiroz - Tech Lipe
5 min readJan 29, 2021

--

Fala pessoal! Beleza?

Seja muito bem vindo(a) a mais um artigo da série “Guia Completo da Elastic Stack”, caso queira conferir os artigos desse série e de outras não deixe de conferir no Portal Techlipe.

O link é esse aqui.

Esse capítulo é a continuação do tópico “Agregações” do Guia Completo.

Breve introdução

Nessa sequência de artigos quero apresentar para você algumas opções de agregações não muito convencionais mas que com certeza são extremamente úteis e que assim que eu as descobri não consigo mais me desapegar.

Um ponto importante também que muitas dessas agregações eu utilizo para otimizar os meus Watchers em produção. Com elas, consegui diminuir a complexidade de código e deixar o trabalho pesado para as agregações, mas isso você pode conferir com mais detalhes na minha série sobre Watchers que está rolando nesse link aqui.

O dataset que vamos trabalhar é o mesmo de movies e a agregação que veremos nesse artigo é a seguinte:

  • Bucket Selector

Motores aquecidos… Vamos lá.

Bucket Selector

Pelas palavras da Elastic, um Bucket Selector Aggregation é isso aqui:

“A parent pipeline aggregation which executes a script which determines whether the current bucket will be retained in the parent multi-bucket aggregation. The specified metric must be numeric and the script must return a boolean value. If the script language is expression then a numeric return value is permitted. In this case 0.0 will be evaluated as false and all other values will evaluate to true.”

Em resumo e na prática, a agregação do tipo Bucket Selector servirá para nós como uma espécie de filtro com base em uma regra, onde a partir dessa regra definiremos se os “buckets” gerados naquela agregação devem ou não ser apresentados como um resultado válido.

Exemplo

Ou seja, vamos supor que temos uma agregação que retorne todos os filmes por ano, e dentro de cada ano (bucket) temos o faturamento total do ano, porém queremos que a apresentação final do resultado da agregação tenha apenas os anos que o faturamento superou os 9Bi de dólares.

Para resolver esse cenário poderíamos utilizar um bucket de date_histogram para separar cada filme em o ano de lançamento, uma subagregação para calcular a soma de faturamento de todos os filmes para cada ano, e, por fim, uma agregação do tipo bucket selector para filtrar e apresentar apenas o resultado que desejamos (>9bi). Ficaria assim:

GET movies/_search
{
"size": 0,
"aggs": {
"filmes_por_ano": {
"date_histogram": {
"field": "release_date",
"interval": "year"
},
"aggs": {
"calcula_faturamento_ano": {
"sum": {
"field": "revenue"
}
},
"filtro_faturamento" : {
"bucket_selector": {
"buckets_path": {
"calcula_faturamento_ano" : "calcula_faturamento_ano"
},
"script": "params.calcula_faturamento_ano > 9000000000L"
}
}}
}
}
}
RESULTADO
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000,
"relation" : "gte"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"filmes_por_ano" : {
"buckets" : [
{
"key_as_string" : "1997-01-01",
"key" : 852076800000,
"doc_count" : 661,
"calcula_faturamento_ano" : {
"value" : 1.1474800169E10
}
},
{
"key_as_string" : "1998-01-01",
"key" : 883612800000,
"doc_count" : 722,
"calcula_faturamento_ano" : {
"value" : 9.941993407E9
}
},
{
"key_as_string" : "1999-01-01",
"key" : 915148800000,
"doc_count" : 723,
"calcula_faturamento_ano" : {
"value" : 1.2134210751E10
}
},
{
"key_as_string" : "2000-01-01",
"key" : 946684800000,
"doc_count" : 789,
"calcula_faturamento_ano" : {
"value" : 1.1615229294E10
}
},
{
"key_as_string" : "2001-01-01",
"key" : 978307200000,
"doc_count" : 865,
"calcula_faturamento_ano" : {
"value" : 1.4133875315E10
}
},
{
"key_as_string" : "2002-01-01",
"key" : 1009843200000,
"doc_count" : 905,
"calcula_faturamento_ano" : {
"value" : 1.5523789818E10
}
},
{
"key_as_string" : "2003-01-01",
"key" : 1041379200000,
"doc_count" : 882,
"calcula_faturamento_ano" : {
"value" : 1.5767126067E10
}
},
{
"key_as_string" : "2004-01-01",
"key" : 1072915200000,
"doc_count" : 992,
"calcula_faturamento_ano" : {
"value" : 1.7666133892E10
}
},
{
"key_as_string" : "2005-01-01",
"key" : 1104537600000,
"doc_count" : 1125,
"calcula_faturamento_ano" : {
"value" : 1.681293657E10
}
},
{
"key_as_string" : "2006-01-01",
"key" : 1136073600000,
"doc_count" : 1270,
"calcula_faturamento_ano" : {
"value" : 1.8368625314E10
}
},
{
"key_as_string" : "2007-01-01",
"key" : 1167609600000,
"doc_count" : 1320,
"calcula_faturamento_ano" : {
"value" : 1.970349411E10
}
},
{
"key_as_string" : "2008-01-01",
"key" : 1199145600000,
"doc_count" : 1473,
"calcula_faturamento_ano" : {
"value" : 2.0655226307E10
}
},
{
"key_as_string" : "2009-01-01",
"key" : 1230768000000,
"doc_count" : 1586,
"calcula_faturamento_ano" : {
"value" : 2.3370045875E10
}
},
{
"key_as_string" : "2010-01-01",
"key" : 1262304000000,
"doc_count" : 1501,
"calcula_faturamento_ano" : {
"value" : 2.344717491E10
}
},
{
"key_as_string" : "2011-01-01",
"key" : 1293840000000,
"doc_count" : 1667,
"calcula_faturamento_ano" : {
"value" : 2.4279042189E10
}
},
{
"key_as_string" : "2012-01-01",
"key" : 1325376000000,
"doc_count" : 1722,
"calcula_faturamento_ano" : {
"value" : 2.605875319E10
}
},
{
"key_as_string" : "2013-01-01",
"key" : 1356998400000,
"doc_count" : 1889,
"calcula_faturamento_ano" : {
"value" : 2.666769839E10
}
},
{
"key_as_string" : "2014-01-01",
"key" : 1388534400000,
"doc_count" : 1974,
"calcula_faturamento_ano" : {
"value" : 2.6443396645E10
}
},
{
"key_as_string" : "2015-01-01",
"key" : 1420070400000,
"doc_count" : 1905,
"calcula_faturamento_ano" : {
"value" : 2.8819362583E10
}
},
{
"key_as_string" : "2016-01-01",
"key" : 1451606400000,
"doc_count" : 1604,
"calcula_faturamento_ano" : {
"value" : 3.0497876509E10
}
},
{
"key_as_string" : "2017-01-01",
"key" : 1483228800000,
"doc_count" : 532,
"calcula_faturamento_ano" : {
"value" : 1.5075894975E10
}
}
]
}
}
}

Como podemos conferir o nosso resultado está filtrado para apenas alguns anos do nosso dataset. Vale lembrar que o mesmo contém filmes desde 1870.

Dentro da estrutura do Bucket Selector temos 2 parâmetros importantes, sendo eles:

  • Buckets_path: Um mapa que contém as variáveis que serão utilizadas no parâmetro script, no nosso exemplo criamos a variável calcula_faturamento_ano que aponta para a agre gação calcula_faturamento_ano. (É possível passar mais de um Buckets_path dentro dessa agregação.
  • Script: Aqui já temos o momento que definimos a regra de seleção para a nossa agregação, onde podemos invocar através dos “params” as variáveis que criamos no Buckets_path.

Conclusão

Espero que você tenha curtido esse capítulo do nosso guia completo onde nesse episódio e (se eu não me engano) nos próximos 2 falamos sobre agregações que me ajudaram (e muito!) em grandes projetos e foram decisivos para sair com uma solução ótima para o cliente, e da mesma forma que me ajudou, espero que te ajude bastante! :D

Muito obrigado!

Referências

Escrito por:

Felipe Queiroz - Tech Lipe para o Portal Techlipe.

--

--

Felipe Queiroz - Tech Lipe

Felipe Queiroz — Data Arch Tech Lead, Embaixador e Certified Engineer da @Elastic e criador do projeto TechLipe