Elasticsearch: queries e filters

Dhyogo Almeida
Fretebras Tech
Published in
4 min readMar 6, 2021

Se você está iniciando a sua jornada no Elasticsearch e deseja aprender sobre queries e filters, você chegou no artigo certo.

Se ainda não leu nada sobre Elasticsearch, recomendo que você comece por aqui:

Após esse merchan do meu outro artigo, vamos ao que interessa!

A forma na qual buscamos os dados no Elasticsearch é feita basicamente utilizando queries e filters. Antes que você tenha a mesma dúvida que eu tive ao começar a utilizá-los, já vou explicar a diferença entre os dois.

Queries

Queries são utilizadas para trazer os dados em termos de relevância, ou seja, o que mais corresponder a consulta que você fez, retornará em um resultado baseado em score.

Filters

São “perguntas” do tipo “sim” e “não”, true ou false, booleano!

Ainda não entendeu? Eu te explico!

Mais especificamente, a diferença entre os dois é que os filtros são geralmente mais rápidos porque verificam apenas se um documento corresponde ou não. Em outras palavras, os filtros fornecem uma resposta booleana, enquanto as consultas retornam uma pontuação calculada de quão bem um documento corresponde a consulta que você fez.

Uma curiosidade sobre filters no Elasticsearch

Filters são armazenados em cache e devem ser usados se a relevância não for importante. Exemplo: se você precisa realizar uma pesquisa em um índice de articles onde é necessário retornar artigos com ano de publicação igual a 2018, utilize filter e não query.

Alguns tipos de queries no Elasticsearch

  • match_all — é o padrão do Elasticsearch, retornando todos os documentos:
{"match_all" : {}}
  • match — faz a busca utilizando analyzer, como exemplo, campos do tipo full-text search:
{"match" : {"title" : "elastic"}}
  • multi_match — realiza a mesma consulta em diversos campos:
{
"multi_match" : {
"query" : "elastic", "fields" : ["title","tags"]
}
}
  • bool — funciona como o filtro bool, mas os resultados são rankeados por relevância.

Alguns tipos de filters no Elasticsearch

  • term filtra pelo valor exato:
{"term" : {"year" : 2018}}
  • terms— retorna se qualquer valor de uma lista for exato:
{"terms" : {"tags" : "elastic", "elasticsearch"}}
  • exists — busca documentos onde um campo existe:
{"exists" : {"field" : "author"}}
  • missing — o oposto do exists, busca documentos onde um campo está faltando:
{"missing" : {"field" : "author"}}
  • range — encontra números ou datas em um intervalo (gt, gte, lt, lte):
{"range" : {"year" : {"gte" : 2018}}}
  • bool — combina filtros com lógica booleana (must (and), must_not (not), should (or)).

Podemos combinar filters dentro de queries e vice-versa.

Para exemplificar um pouco do que foi dito acima, vamos buscar artigos no índice articles, onde no título tenha a palavra elastic e que o ano do artigo seja maior ou igual a 2018:

curl -H "Content-type: application/json" -X GET 127.0.0.1:9200/articles/_search -d '
{
"query" : {
"bool" : {
"must" : {"term" : {"title" : "elastic"}},
"filter" : {"range" : {"year" : {"gte" : 2018}}}
}
}
}'

Query do tipo match_phrase

Temos que estar cientes de que match_phrase é utilizado para trazer resultados buscando os termos na ordem certa. Um exemplo seria uma consulta onde queremos trazer artigos com o título "elasticsearch conceito":

curl -H "Content-type: application/json" -X GET 127.0.0.1:9200/articles/_search -d '
{
"query" : {
"match_phrase" : {
"title" : {
"query" : "elasticsearch conceito"
}
}
}
}

Utilizando o match_phrase, a consulta não retornaria caso eu invertesse a sentença para "conceito elasticsearch". Mas existe uma solução para isso caso você queira que o mesmo resultado apareça tanto para "elasticsearch conceito" quando para "conceito elasticsearch".

Te apresento o slop

No match_phrase ordem importa, mas pode haver algumas palavras entre os termos procurados. O slop representa o quanto você quer que um termo se movimente para satisfazer uma frase em ambas as direções.
Exemplo: slop de 1 para "elasticsearch conceito" retornaria também para "conceito elasticsearch".

curl -H "Content-type: application/json" -X GET 127.0.0.1:9200/articles/_search -d '
{
"query" : {
"match_phrase" : {
"title" : {
"query" : {"elasticsearch conceito", "slop" : 1}
}
}
}
}

E se houvesse uma outra palavra entre conceito e elasticsearch, como por exemplo: "conceito de elasticsearch" e buscássemos "conceito elasticsearch"? O slop de 1 também resolveria, visto que o 1 corresponde a quantidade de sentenças que a busca pode "pular" para corresponder:

curl -H "Content-type: application/json" -X GET 127.0.0.1:9200/articles/_search -d '
{
"query" : {
"match_phrase" : {
"title" : {
"query" : {"conceito de elasticsearch", "slop" : 1}
}
}
}
}

Proximity queries

Os resultados de uma busca utilizando query são ordenados por relevância. Você pode usar um slop com valor alto se quiser retornar documentos que tenha palavras de sua frase. É importante ressaltar que documentos que tenham palavras mais próximos umas das outras nas quais você pesquisou, têm maior pontuação, ou seja, são mais relevantes:

{
"query" : {
"match_phrase" : {
"title" : {
"query" : {"elasticsearch conceito", "slop" : 50}
}
}
}
}

O Elasticsearch é repleto de recursos e também é muito poderoso. Espero que tenham gostado. Até a próxima!

--

--

Dhyogo Almeida
Fretebras Tech

Tech Lead | Senior Software Engineer — Fretebras.