Guia de Elasticsearch em Java

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.