
Tá acabando cara, calma, não é só você que não vê a hora disso acabar, rs. N Tem esse e mais um artigo que vai explicar como usar isso junto com o Logstash, vai ser bem legal cara! Confie! Você vai ganhar dinheiro com isso, rs!
Só te animando achei esses exemplos os mais divertidos e fáceis de fazer, tem uma comparação bem real com SQL então você DBA enferrujado que nem eu vai tirar de letra! Só que vamos começar com uma dica, como realizar um processo de BULK no ElasticSearch.
Processo de BULK:
Esse é um processo importante do ElasticSearch que devemos aprender caso queiram realizar a criação de um índice inserindo um grande volume de dados de uma única vez. Nesse exemplo vamos criar o index “vehicles”, segue o link abaixo para download desse bulk no git:
wget https://github.com/AnselmoDBA/elasticsearch/blob/master/vehicles.dsl
Note que no início desse arquivo a linha POST tem o parâmetro _bulk, que não tínhamos visto antes:
POST /vehicles/cars/_bulk
Em conjunto com esse parâmetro fazemos a inserção linha a linha dos dados que estamos cadastrando no index em um único comando, sendo assim, as linhas ficam da seguinte forma:
{ "index": {}}
{ "price" : 10000, "color" : "white", "make" : "honda", "sold" : "2016-10-28", "condition": "okay"}
A primeira linha index, é sempre padrão: { “index”: {}}
Já a segunda linha é basicamente, chave : valor, chave : valor, e assim vai.
Isso é ideal para grandes carregamentos de arquivos, para os nossos exemplos, crie o índice com o script indicado.
Limitando os resultados (LIMIT)
Nessa parte vamos ver como criar sitaxes como limit (limita o numero de registros exibidos numa query) e ordenar os dados tipo ORDER BY e ORDER BY DESC, vamos começar com o LIMIT:
Vamos supor que assim como esse bulk do index vehicles que criamos nós tenhamos mais do que 10 registros, por padrão quando fazemos uma busca match_all ou outras, caso existam mais de 10 registros no Kibana ele exibe só 10, então podemos usar o parâmetro “size” para limitar o numero de registros e se necessário o “from” em conjunto com ele para limitar onde começa e termina os registros, veja os exemplos abaixo:
Exibindo 13 registros da busca
get /vehicles/cars/_search
{
"size": 13,
"query": {
"match_all": {}
}
}
Exibindo somente 5 registros que vão do primeiro ao 5o.
get /vehicles/cars/_search
{
"from": 0,
"size": 5,
"query": {
"match_all": {}
}
}
Agora vamos ver como ordenar os dados extraídos assim como um order by no SQL, as ordens de ASC e DESC são as mesmas, portanto lembre que o padrão é ascendente, nesse exemplo estamos ordenando os preços dos carros do maior para o menor:
Realizando um COUNT:
Você já percebeu que sempre que fazemos uma busca, no argumento total, já vem o numero de registros que o ElasticSearch trás, porem nós usamos o _search na primeira linha, nesse exemplo, vamos fazer um count com o numero de veículos que são da marca Dodge:
get /vehicles/cars/_count
{
"query": {
"match":{"make" : "dodge"}
}
}
--- Resultado:
{
"count": 5,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
}
}
Realizando um MAX, MIN, AVG e um GROUP BY:
Nesse exemplo vamos trazer os seguintes dados:
- Contagem veículos por marca
- Valor médio desses veículos separados por marca
- Preço máximo desses veículos separados por marca
- Preço mínimo desses veículos separados por marca
Com essas consultas vamos ver como realizar MIN (Valor minimo), MAX (Valor máximo) e AVG (Média), lembrando que estamos fazendo uma analogia com SQL mas é muito parecido, veja a consulta abaixo:
get /vehicles/cars/_search
{
"aggs":{
"carros_populares": {
"terms": {
"field": "make.keyword"
},
"aggs": {
"preco_medio": {
"avg": {
"field": "price"
}
},
"preco_max": {
"max": {
"field": "price"
}
},
"preco_min": {
"min": {
"field": "price"
}
}
}
}
}
}
}
Em resumo usamos o comando “aggs” o qual faz o agrupamento, onde o primeiro separou os tipos de veiculos por marca, dentro desse primeiro grupo, estamos criando outras 3 métricas, preco_medio (avg), preco_max(max) e preco_min(min), indo no resultado esses agrupamentos sempre ficam no final do resultado, no Kibana quando minimizamos o campo hits, o próximo é aggregations onde podemos ver nossos agrupamentos segue abaixo os exemplos:

"aggregations": {
"carros_populares": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "dodge",
"doc_count": 5,
"preco_max": {
"value": 35000
},
"preco_medio": {
"value": 18900
},
"preco_min": {
"value": 10000
}
},
{
"key": "chevrolet",
"doc_count": 3,
"preco_max": {
"value": 28000
},
"preco_medio": {
"value": 20333.333333333332
},
"preco_min": {
"value": 13000
}
},
{
"key": "bmw",
"doc_count": 2,
"preco_max": {
"value": 80000
},
"preco_medio": {
"value": 55000
},
"preco_min": {
"value": 30000
}
},
{
"key": "ford",
"doc_count": 2,
"preco_max": {
"value": 30000
},
"preco_medio": {
"value": 27500
},
"preco_min": {
"value": 25000
}
},
{
"key": "honda",
"doc_count": 2,
"preco_max": {
"value": 20000
},
"preco_medio": {
"value": 15000
},
"preco_min": {
"value": 10000
}
},
{
"key": "toyota",
"doc_count": 2,
"preco_max": {
"value": 15000
},
"preco_medio": {
"value": 13500
},
"preco_min": {
"value": 12000
}
}
]
}
}
}
Agora como último exemplo, vamos fazer uma query e com base nelas criar esses agrupamentos, nesse nosso exemplo ele está pegando essas métricas de todos os registros, vamos limitar isso somente aos carros de cor vermelha, só para que não venham os dados e sim somente os cálculos vamos usar a clausula “size” igual a 0, sendo assim só teremos as médias e outros valores:
get /vehicles/cars/_search
{
"size":0,
"query":{
"match":{"color": "red"}
},
"aggs":{
"carros_populares": {
"terms": {
"field": "make.keyword"
},
"aggs": {
"preco_medio": {
"avg": {
"field": "price"
}
},
"preco_max": {
"max": {
"field": "price"
}
},
"preco_min": {
"min": {
"field": "price"
}
}
}
}
}
}
}
Ao invés de 16 veículos temos somente 5, os quais são agrupados e calculados conforme a consulta:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 0,
"hits": []
},
"aggregations": {
"carros_populares": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "dodge",
"doc_count": 3,
"preco_max": {
"value": 35000
},
"preco_medio": {
"value": 24000
},
"preco_min": {
"value": 18000
}
},
{
"key": "bmw",
"doc_count": 1,
"preco_max": {
"value": 80000
},
"preco_medio": {
"value": 80000
},
"preco_min": {
"value": 80000
}
},
{
"key": "chevrolet",
"doc_count": 1,
"preco_max": {
"value": 20000
},
"preco_medio": {
"value": 20000
},
"preco_min": {
"value": 20000
}
}
]
}
}
}
Trazendo tudo isso de uma vez (STATS):
Sacaneando você que fez um por um, existe um comando no ElasticSearch que traz todas essas métricas de uma vez, esse comando é o stats, vamos eliminar todos os argumentos desde a média e vamos usar um único comando:
get /vehicles/cars/_search
{
"size":0,
"query":{
"match":{"color": "red"}
},
"aggs":{
"carros_populares": {
"terms": {
"field": "make.keyword"
},
"aggs": {
"dados_dos_precos": {
"stats": {
"field": "price"
}
}
}
}
}
}
}
}
Observe agora todos os dados no relatório final (MAX, MIN, AVG, SUM):
{
"took": 77,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 0,
"hits": []
},
"aggregations": {
"carros_populares": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "dodge",
"doc_count": 3,
"dados_dos_precos": {
"count": 3,
"min": 18000,
"max": 35000,
"avg": 24000,
"sum": 72000
}
},
{
"key": "bmw",
"doc_count": 1,
"dados_dos_precos": {
"count": 1,
"min": 80000,
"max": 80000,
"avg": 80000,
"sum": 80000
}
},
{
"key": "chevrolet",
"doc_count": 1,
"dados_dos_precos": {
"count": 1,
"min": 20000,
"max": 20000,
"avg": 20000,
"sum": 20000
}
}
]
}
}
}
Criando agrupamentos por Range:
Vimos nos artigos anteriores o comando range e vamos usa-lo também para a criação de argumentos, nesse exemplo vamos fazer uma separação do numero de vendas dentro de 2 períodos:
- Periodo 1: 2016-01-01 até 2016-05-18
- Periodo 2: 2016-05-18 até 2017-01-01
Vamos fazer esses ranges contabilizando pelo campo sold, sendo assim:
get /vehicles/cars/_search
{
"size":0,
"aggs":{
"carros_populares": {
"terms": {
"field": "make.keyword"
},
"aggs": {
"vendidos_por_periodo": {
"range": {
"field": "sold",
"ranges": [
{
"from": "2016-01-01", "to": "2016-05-18"
},
{
"from": "2016-05-18", "to": "2017-01-01"
}
]
}
}
}
}
}
}
}
}
De todos os veículos que temos cadastrados, seguem as métricas tiradas:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 16,
"max_score": 0,
"hits": []
},
"aggregations": {
"carros_populares": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "dodge",
"doc_count": 5,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 4
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 1
}
]
}
},
{
"key": "chevrolet",
"doc_count": 3,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 0
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 3
}
]
}
},
{
"key": "bmw",
"doc_count": 2,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 1
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 1
}
]
}
},
{
"key": "ford",
"doc_count": 2,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 0
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 2
}
]
}
},
{
"key": "honda",
"doc_count": 2,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 0
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 2
}
]
}
},
{
"key": "toyota",
"doc_count": 2,
"vendidos_por_periodo": {
"buckets": [
{
"key": "2016-01-01T00:00:00.000Z-2016-05-18T00:00:00.000Z",
"from": 1451606400000,
"from_as_string": "2016-01-01T00:00:00.000Z",
"to": 1463529600000,
"to_as_string": "2016-05-18T00:00:00.000Z",
"doc_count": 0
},
{
"key": "2016-05-18T00:00:00.000Z-2017-01-01T00:00:00.000Z",
"from": 1463529600000,
"from_as_string": "2016-05-18T00:00:00.000Z",
"to": 1483228800000,
"to_as_string": "2017-01-01T00:00:00.000Z",
"doc_count": 2
}
]
}
}
]
}
}
}
Existe um doc_count geral da primeira busca de tipos de veículos e dentro de cada range existe outro doc_count que fala o numero de veículos vendidos por range.
Bom, acho que na parte de consultas e agrupamentos já vimos bastante, o restante fica por conta de treino e documentação da própria ElasticSearch que pode ser encontrada no link abaixo:
No próximo e último artigo! (Graças a Deus), vamos por a mão na massa, usando o Logstash e criar alguns dashboard bonitos de mostrar pro chefe no Kibana.
Até o próximo!
Anselmo Borges