Guia de Elasticsearch em Java
1. Visão geral
Neste artigo, vamos mergulhar em alguns conceitos-chave relacionados aos mecanismos de pesquisa de texto completo, com foco especial no Elasticsearch.
Como este é um artigo orientado a Java, não vamos dar um tutorial detalhado passo a passo sobre como configurar o Elasticsearch e mostrar como ele funciona nos bastidores, em vez disso, vamos direcionar o cliente Java, e como usar os principais recursos comoindex,delete,getesearch.
2. Configuração
Para instalar o Elasticsearch em sua máquina, consulteofficial setup guide.
O processo de instalação é bastante simples, basta baixar o pacote zip / tar e executar o arquivo de scriptelasticsearch (elasticsearch.bat para usuários do Windows).
Por padrão, o Elasticsearch escuta a porta 9200 para consultas HTTP futuras por padrão. Podemos verificar se ele foi iniciado com sucesso abrindo o URLhttp://localhost:9200/ em seu navegador favorito:
{
"name" : "GEpcsab",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "z3FfAe6gRMmSmeWBIOihJg",
"version" : {
"number" : "5.6.10",
"build_hash" : "b727a60",
"build_date" : "2018-06-06T15:48:34.860Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
3. Configuração do Maven
Agora que temos nosso cluster Elasticsearch básico instalado e funcionando, vamos direto ao cliente Java. Primeiro de tudo, precisamos ter o seguinteMaven dependency declarado em nosso arquivopom.xml:
org.elasticsearch
elasticsearch
5.6.0
Você sempre pode verificar as versões mais recentes hospedadas pelo Maven Central com o link fornecido anteriormente.
4. API Java
Antes de irmos direto para como usar os principais recursos da API Java, precisamos iniciar o cliente de transporte:
Client client = new PreBuiltTransportClient(
Settings.builder().put("client.transport.sniff", true)
.put("cluster.name","elasticsearch").build())
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
4.1. Documentos de indexação
A funçãoprepareIndex() permite armazenar um documento JSON arbitrário e torná-lo pesquisável:
@Test
public void givenJsonString_whenJavaObject_thenIndexDocument() {
String jsonObject = "{\"age\":10,\"dateOfBirth\":1471466076564,"
+"\"fullName\":\"John Doe\"}";
IndexResponse response = client.prepareIndex("people", "Doe")
.setSource(jsonObject, XContentType.JSON).get();
String id = response.getId();
String index = response.getIndex();
String type = response.getType();
long version = response.getVersion();
assertEquals(Result.CREATED, response.getResult());
assertEquals(0, version);
assertEquals("people", index);
assertEquals("Doe", type);
}
Ao executar o teste, certifique-se de declarar a variávelpath.home, caso contrário, a seguinte exceção pode surgir:
java.lang.IllegalStateException: path.home is not configured
Depois de executar o comando Maven:mvn clean install -Des.path.home=C:\elastic, o documento JSON será armazenado compeople como índice eDoe como tipo.
Observe que é possível usarany JSON Java library para criar e processar seus documentos. If you are not familiar with any of these, you can use Elasticsearch helpers to generate your own JSON documents:
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("fullName", "Test")
.field("dateOfBirth", new Date())
.field("age", "10")
.endObject();
IndexResponse response = client.prepareIndex("people", "Doe")
.setSource(builder).get();
assertEquals(Result.CREATED, response.getResult());
4.2. Consulta a documentos indexados
Agora que temos um documento JSON pesquisável digitado indexado, podemos prosseguir e pesquisar usando o métodoprepareSearch():
SearchResponse response = client.prepareSearch().execute().actionGet();
List searchHits = Arrays.asList(response.getHits().getHits());
List results = new ArrayList();
searchHits.forEach(
hit -> results.add(JSON.parseObject(hit.getSourceAsString(), Person.class)));
The results returned by the actionGet() method are called Hits, cadaHit se refere a um documento JSON que corresponde a uma solicitação de pesquisa.
Nesse caso, a listaresults contém todos os dados armazenados no cluster. Observe que, neste exemplo, estamos usando a bibliotecaFastJson para converter JSONStrings em objetos Java.
Podemos aprimorar a solicitação adicionando parâmetros adicionais para personalizar a consulta usando os métodosQueryBuilders:
SearchResponse response = client.prepareSearch()
.setTypes()
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setPostFilter(QueryBuilders.rangeQuery("age").from(5).to(15))
.execute()
.actionGet();
4.3. Recuperando e Excluindo Documentos
Os métodosprepareGet()eprepareDelete() permitem obter ou excluir um documento JSON do cluster usando seu id:
GetResponse response = client.prepareGet("people","Doe","1").get();
String age = (String) response.getField("age").getValue();
// Process other fields
DeleteResponse response = client.prepareDelete("people", "Doe", "5")
.get();
A sintaxe é bastante direta, você só precisa especificar o índice e o valor do tipo junto com o id do objeto.
5. QueryBuilders Exemplos
A classeQueryBuilders fornece uma variedade de métodos estáticos usados como correspondências dinâmicas para localizar entradas específicas no cluster. Ao usar o métodoprepareSearch() para procurar documentos JSON específicos no cluster, podemos usar construtores de consulta para personalizar os resultados da pesquisa.
Aqui está uma lista dos usos mais comuns da APIQueryBuilders.
O métodomatchAllQuery() retorna um objetoQueryBuilder que corresponde a todos os documentos no cluster:
QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
OrangeQuery() corresponde a documentos onde o valor de um campo está dentro de um determinado intervalo:
QueryBuilder matchDocumentsWithinRange = QueryBuilders
.rangeQuery("price").from(15).to(100)
Fornecendo um nome de campo - por exemplo fullName, e o valor correspondente - por exemplo John Doe, o métodomatchQuery() corresponde a todos os documentos com o valor desses campos exatos:
QueryBuilder matchSpecificFieldQuery= QueryBuilders
.matchQuery("fullName", "John Doe");
Também podemos usar o métodomultiMatchQuery() para construir uma versão de vários campos da consulta de correspondência:
QueryBuilder matchSpecificFieldQuery= QueryBuilders.matchQuery(
"Text I am looking for", "field_1", "field_2^3", "*_field_wildcard");
We can use the caret symbol (^) to boost specific fields.
Em nosso exemplo, ofield_2 tem um valor de boost definido como três, tornando-o mais importante do que os outros campos. Observe que é possível usar curingas e consultas regex, mas em termos de desempenho, tome cuidado com o consumo de memória e o atraso no tempo de resposta ao lidar com curingas, porque algo como * _apples pode causar um grande impacto no desempenho.
O coeficiente de importância é usado para ordenar o conjunto de resultados de acertos retornados após a execução do métodoprepareSearch().
Se você estiver mais familiarizado com a sintaxe de consultas Lucene, você pode usar osimpleQueryStringQuery() method to customize search queries:
QueryBuilder simpleStringQuery = QueryBuilders
.simpleQueryStringQuery("+John -Doe OR Janette");
Como você provavelmente pode imaginar,we can use the Lucene’s Query Parser syntax to build simple, yet powerful queries. Aqui estão alguns operadores básicos que podem ser usados junto com os operadoresAND/OR/NOT para construir consultas de pesquisa:
-
O operador necessário (+): requer que um pedaço específico de texto exista em algum lugar dos campos de um documento.
-
O operador de proibição (–): exclui todos os documentos que contêm uma palavra-chave declarada após o símbolo (–).
6. Conclusão
Neste artigo rápido, vimos como usar a API Java do ElasticSearch para executar alguns dos recursos comuns relacionados aos mecanismos de pesquisa de texto completo.
Você pode verificar o exemplo fornecido neste artigo noGitHub project.