Introdução rápida à pesquisa de texto completo com ElasticSearch
1. Visão geral
A pesquisa de texto completo consulta e realiza pesquisas linguísticas em documentos. Inclui palavras ou frases únicas ou múltiplas e retorna documentos que correspondem à condição de pesquisa.
ElasticSearch é um mecanismo de busca baseado emApache Lucene, uma biblioteca de software de recuperação de informação gratuita e de código aberto. Ele fornece um mecanismo de pesquisa distribuído de texto completo com uma interface da Web HTTP e documentos JSON sem esquema.
Este artigo examina a API REST do ElasticSearch e demonstra operações básicas usando apenas solicitações HTTP.
2. Configuração
Para instalar o ElasticSearch em sua máquina, consulteofficial setup guide.
A API RESTfull é executada na porta 9200. Vamos testar se está sendo executado corretamente usando o seguinte comando curl:
curl -XGET 'http://localhost:9200/'
Se você observar a seguinte resposta, a instância está sendo executada corretamente:
{
"name": "NaIlQWU",
"cluster_name": "elasticsearch",
"cluster_uuid": "enkBkWqqQrS0vp_NXmjQMQ",
"version": {
"number": "5.1.2",
"build_hash": "c8c4c16",
"build_date": "2017-01-11T20:18:39.146Z",
"build_snapshot": false,
"lucene_version": "6.3.0"
},
"tagline": "You Know, for Search"
}
3. Documentos de indexação
O ElasticSearch é orientado a documentos. Ele armazena e indexa documentos. A indexação cria ou atualiza documentos. Após a indexação, você pode pesquisar, classificar e filtrar documentos completos, não linhas de dados colunares. Essa é uma maneira fundamentalmente diferente de pensar sobre dados e é um dos motivos pelos quais o ElasticSearch pode executar uma pesquisa complexa em texto completo.
Os documentos são representados como objetos JSON. A serialização JSON é suportada pela maioria das linguagens de programação e se tornou o formato padrão usado pelo movimento NoSQL. É simples, conciso e fácil de ler.
Usaremos as seguintes entradas aleatórias para realizar nossa pesquisa de texto completo:
{
"title": "He went",
"random_text": "He went such dare good fact. The small own seven saved man age."
}
{
"title": "He oppose",
"random_text":
"He oppose at thrown desire of no. \
Announcing impression unaffected day his are unreserved indulgence."
}
{
"title": "Repulsive questions",
"random_text": "Repulsive questions contented him few extensive supported."
}
{
"title": "Old education",
"random_text": "Old education him departure any arranging one prevailed."
}
Antes de podermos indexar um documento, precisamos decidir onde armazená-lo. É possível ter vários índices, que por sua vez contêm vários tipos. Esses tipos contêm vários documentos e cada documento possui vários campos.
Vamos armazenar nossos documentos usando o seguinte esquema:
text: o nome do índice. article: o nome do tipo. id: O ID desta entrada de texto de exemplo particular.
Para adicionar um documento, vamos executar o seguinte comando:
curl -XPUT 'localhost:9200/text/article/1?pretty'
-H 'Content-Type: application/json' -d '
{
"title": "He went",
"random_text":
"He went such dare good fact. The small own seven saved man age."
}'
Aqui estamos usandoid=1, podemos adicionar outras entradas usando o mesmo comando e id incrementado.
4. Recuperando documentos
Depois de adicionar todos os nossos documentos, podemos verificar quantos documentos, usando o seguinte comando, temos no cluster:
curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
"query": {
"match_all": {}
}
}'
Além disso, podemos obter um documento usando seu ID com o seguinte comando:
curl -XGET 'localhost:9200/text/article/1?pretty'
E devemos obter a seguinte resposta da pesquisa elástica:
{
"_index": "text",
"_type": "article",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"title": "He went",
"random_text":
"He went such dare good fact. The small own seven saved man age."
}
}
Como podemos ver, esta resposta corresponde à entrada adicionada usando o ID 1.
5. Consultando Documentos
OK, vamos realizar uma pesquisa de texto completo com o seguinte comando:
curl -XGET 'localhost:9200/text/article/_search?pretty'
-H 'Content-Type: application/json' -d '
{
"query": {
"match": {
"random_text": "him departure"
}
}
}'
E obtemos o seguinte resultado:
{
"took": 32,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1.4513469,
"hits": [
{
"_index": "text",
"_type": "article",
"_id": "4",
"_score": 1.4513469,
"_source": {
"title": "Old education",
"random_text": "Old education him departure any arranging one prevailed."
}
},
{
"_index": "text",
"_type": "article",
"_id": "3",
"_score": 0.28582606,
"_source": {
"title": "Repulsive questions",
"random_text": "Repulsive questions contented him few extensive supported."
}
}
]
}
}
Como podemos ver, estamos procurando“him departure”e obtemos dois resultados com pontuações diferentes. O primeiro resultado é óbvio porque o texto contém a busca realizada dentro dele e como podemos ver temos a pontuação de1.4513469.
O segundo resultado é recuperado porque o documento de destino contém a palavra "ele".
Por padrão, o ElasticSearch classifica os resultados correspondentes por sua pontuação de relevância, ou seja, pela qualidade de cada documento correspondente à consulta. Observe que a pontuação do segundo resultado é pequena em relação ao primeiro hit, indicando menor relevância.
6. Fuzzy Search
A correspondência difusa trata duas palavras que são "confusas" semelhantes como se fossem a mesma palavra. Primeiro, precisamos definir o que queremos dizer com imprecisão.
O Elasticsearch suporta uma distância máxima de edição, especificada com o parâmetro de imprecisão, 2. O parâmetro de imprecisão pode ser definido como AUTO, o que resulta nas seguintes distâncias máximas de edição:
-
0 para strings de um ou dois caracteres
-
1 para sequências de três, quatro ou cinco caracteres
-
2 para sequências de mais de cinco caracteres
você pode descobrir que uma distância de edição de2 retorna resultados que não parecem estar relacionados.
Você pode obter melhores resultados e melhor desempenho com uma imprecisão máxima de 1. Distância refere-se à distância de Levenshtein, que é uma métrica de cadeia para medir a diferença entre duas seqüências. Informalmente, oLevenshtein distance entre duas palavras é o número mínimo de edições de um único caractere.
OK, vamos realizar nossa pesquisa com confusão:
curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query":
{
"match":
{
"random_text":
{
"query": "him departure",
"fuzziness": "2"
}
}
}
}'
E aqui está o resultado:
{
"took": 88,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 1.5834423,
"hits": [
{
"_index": "text",
"_type": "article",
"_id": "4",
"_score": 1.4513469,
"_source": {
"title": "Old education",
"random_text": "Old education him departure any arranging one prevailed."
}
},
{
"_index": "text",
"_type": "article",
"_id": "2",
"_score": 0.41093433,
"_source": {
"title": "He oppose",
"random_text":
"He oppose at thrown desire of no.
\ Announcing impression unaffected day his are unreserved indulgence."
}
},
{
"_index": "text",
"_type": "article",
"_id": "3",
"_score": 0.2876821,
"_source": {
"title": "Repulsive questions",
"random_text": "Repulsive questions contented him few extensive supported."
}
},
{
"_index": "text",
"_type": "article",
"_id": "1",
"_score": 0.0,
"_source": {
"title": "He went",
"random_text": "He went such dare good fact. The small own seven saved man age."
}
}
]
}
}'
Como podemos ver, a imprecisão nos dá mais resultados.
Precisamos usar a imprecisão com cuidado, porque ela tende a recuperar resultados que parecem não relacionados.
7. Conclusão
Neste tutorial rápido nos concentramos emindexing documents and querying Elasticsearch for full-text search, directly via it’s REST API.
Obviamente, temos APIs disponíveis para várias linguagens de programação quando precisamos - mas a API ainda é bastante conveniente e independente da linguagem.