Uma Introdução à Query DSL: Criação de Queries em Elasticsearch

O que são as queries obtidas quase em tempo real do Elasticsearch? Como é possível escrevê-las de modo a tirar o máximo partido desta ferramenta? Estas são as perguntas a que vou responder neste artigo, para que possamos explorar juntos as potencialidades do Elasticsearch.


Já sabemos que o Elasticsearch é uma poderosa base de dados não-relacional visto que executa as suas queries quase em tempo real – caso não saibas nada sobre o Elasticsearch, aqui vai uma introdução a esta fantástica ferramenta.

Mas em que consistem estas queries? E como podemos escrevê-las para conseguirmos realizar as operações Get e Post e assim tirar o melhor partido do ES? São as perguntas a que vou responder neste artigo, para que possas explorar ao máximo as potencialidades do Elasticsearch.

Para exemplificar o que vou explicar, usarei o Postman para consultar um índice existente com informações e exibir a resposta da requisição, para que consigas compreender o que aconteceu.

Pronto para explorar um pouco mais sobre as queries do Elasticsearch?


Query DSL – perceber o que é


Quando falamos de Query DSL, é importante definir, antes de mais nada, que o Elasticsearch invoca a maioria das suas APIs para fornecer queries baseadas em JSON, que são utilizadas de diferentes formas para fazer operações como pesquisa e persistência de dados.

Todas as queries retornam uma propriedade chamada score para cada objeto, que representa o quanto esse resultado satisfaz o filtro fornecido.

Dentro deste contexto, existem dois tipos de cláusulas, sendo elas:

  • Leaf Query Clauses − Estas cláusulas procuram valores específicos em campos específicos de um índice, usando funções tais como match, term ou range para isolar e recuperar dados com base no valor especificado;
  • Compound Query Clauses – Estas cláusulas são uma combinação de Leaf Query Clauses e são utilizadas para combinar os resultados de outras queries para procurar novos resultados.


Tipos de queries


Match All Query


Esta é a query mais básica, que tem como objetivo ir buscar todos os dados de um índice e, neste caso, todos os scores serão 1.0, já que esta consulta não depende de nenhuma condição. 

Vale a pena salientar que a Match All Query pode ser simplificada através da utilização do URL http://localhost:usedport/users/search?pretty=true.

Esta é a utilização da Match All Query:

img-1


E o resultado é retornado em formato JSON, exactamente como o ES funciona:

img-3
img-5
img-7
img-9


Como podemos ver nesta resposta, o score de cada registo é 1.0, o que significa que não há nada a comparar entre si.


Match Query


Ao contrário da Match All Query, a Match Query é representada por uma ou mais condições que a query deve satisfazer. Caracteriza-se pela correspondência de um termo ou expressão com os valores de um ou mais campos.

Este é um exemplo da utilização de uma match query no índice que foi consultado acima:

img-11


Na resposta, podemos observar que todos os registos com o campo “category” com o valor igual a “Books” foram devolvidos, tendo cada um deles um score específico que representa o quanto o valor do campo é parecido com o termo pesquisado. Independentemente do quanto o termo corresponde ao valor, os scores serão sempre diferentes devido ao processo de análise do ES. 

img-13
img-15


Multi Match Query


Esta query é utilizada para corresponder a uma condição (retornar uma palavra ou uma expressão) num ou mais campos. Por outras palavras, a Multi Match Query procura um termo em quantos campos tu especifiques.

img-17


Repara que esta query procura o termo “soccer” em ambos os campos “tags” e “name”. Agora vamos analisar a resposta:

img-19
img-21
img-23


É interessante olhar para o score de cada registo e como este se altera devido à semelhança entre os termos e os campos. Aqui, os registos que contêm “soccer” em ambos os campos consultados têm um score mais alto do que os que correspondem apenas a uma condição.


Term Level Queries


Esta query tem a mesma funcionalidade que a Match Query, porém a diferença é que as Term Level Queries são mais recomendadas para lidar com dados estruturados como números, datas e enums.

No exemplo, podemos ver que o campo em que procuramos um valor específico é do tipo numérico e precisa de ser totalmente igual ao valor fornecido.

img-25


A resposta vai retornar o único registo que corresponde ao valor do campo “price” igual a 29.9, com o score 1.0, porque este é uma query do tipo numérico com o valor que corresponde exatamente ao que estamos à procura.

img-27


Range Queries


Esta query é utilizada para filtrar dados entre uma gama de valores, para isso podemos utilizar quatro operadores: 

  • gte − maior que ou igual a


Este operador é utilizado para filtrar dados cujos valores filtrados são superiores ou iguais a um valor especificado;

  • gt – maior que


Este operador é utilizado para filtrar dados cujos valores filtrados são apenas superiores a um valor especificado;

  • lte − menor que ou igual a


Este filtra por valores inferiores ou iguais ao valor especificado.

  • lt – menos que


Ao contrário do lte, o operador lt filtra apenas por valores que são inferiores ao valor que estamos a procurar.

Agora vamos fazer um exemplo de cada operador:

  • gte

img-29



Neste caso, estamos a procurar todos os produtos cujo preço seja superior ou igual a um valor específico, e depois podemos observar que todos os dados retornados respeitam esta condição:

img-31
img-33
img-35


gt

img-37


Neste exemplo, pode ser observado que, agora que estamos a restringir a pesquisa apenas aos produtos cujo preço é superior a um valor específico, a consulta retorna apenas três registos em vez de quatro (um registo a menos do que o gte):

img-39
img-41


lte

img-43


Vai ser apenas retornado um registo, cujo preço é inferior ou igual a 29.9:

img-45
img-47


lt


É muito interessante observar, neste exemplo, que quando restringimos o valor a ser apenas inferior ao valor que estamos a filtrar, não é retornado nenhum registo, o que significa que o preço mínimo de todos os registos neste índice é 29.9:

img-49
img-51


Compound Queries


Tal como referido no início deste artigo, uma Compound Query é representada por uma união de Leaf Queries, através da utilização de boolean operators para conseguir as comparações e devolver valores que satisfaçam todas as condições impostas.

No exemplo abaixo, estamos à procura de registos cujo campo “category” corresponde a “Books” OU “Sports”. Tal é possível devido ao termo “should”, que suporta o número de condições de que necessitamos. Também podemos observar que estamos a acrescentar uma condição AND que é representada pelo operador “must”, que restringe o “price” a ser superior a 50 e inferior a 100.

Não é tão interessante combinar queries?

img-53


E a resposta representa exatamente o que estamos à procura:

img-55
img-57


Uma introdução à Query DSL: criação de queries em Elasticsearch – Considerações Finais


Trabalhar com Elasticsearch, além de ser escalável, é também flexível devido à possibilidade de consultar informação dentro de um índice que vai responder às tuas necessidades – que pode ser uma pesquisa simples para todos os registos, ou pode ser uma pesquisa complexa e repleta de condições.

Proponho que cries um índice e treines mais do que os exemplos mostrados, para que possas usufruir ao máximo desta ferramenta!