Prefácio
No artigo anterior, Springboot, Mybatis, Druid e PageHelper foram integrados e as operações de várias fontes de dados foram implementadas. Este artigo apresenta e usa principalmente o ElastisEarch, o mecanismo de pesquisa mais popular e o usa em combinação com o Springboot.
Introdução ao Elasticsearch
Elasticsearch é um servidor de pesquisa baseado no Lucene. Na verdade, ele encapsula o Lucene e fornece a interface de operação da API REST. Elasticsearch é um mecanismo de pesquisa e análise de texto completo altamente escalável que pode ser usado para armazenar, pesquisar e analisar rapidamente o Big Data.
Os principais recursos do Elasticsearch: distribuído, alta disponibilidade, escrita assíncrona, multi-api, orientada a documentos.
Elasticsearch Core Concepts: quase em tempo real, cluster, nó (Salvar dados), índice, shard (slicing índice shards), réplicas (o fatiamento pode definir várias réplicas). Ele pode armazenar, pesquisar e analisar rapidamente quantidades enormes de dados.
Elasticsearch Casos de uso: Wikipedia, transbordamento de pilha, github, etc.
O Springboot integra o Elasticsearch
Antes de usar o Springboot para integrar o Elasticsearch, devemos entender o relacionamento entre eles.
| Versão da inicialização da primavera (x) | Spring Data Elasticsearch Version (y) | Elasticsearch Version (Z) |
|---|---|---|
| x <= 1.3.5 | y <= 1.3.4 | z <= 1.7.2* |
| x> = 1.4.x | 2.0.0 <= y <5.0.0 ** | 2.0.0 <= z <5.0.0 ** |
A versão do Springboot que estamos usando aqui é 1.5.9, e a versão do Elasticsearch é 2.3.5.
Usando o Springboot para integrar o Elasticsearch, geralmente é encapsulado usando o SpringData e, em seguida, a interface da camada DAO herda a classe ElasticsearchRepository. Esta classe implementa muitos métodos, como o método CRUD comumente usado.
Uso de Springdata
Primeiro, faça os preparativos relevantes antes do uso.
A configuração do Maven é a seguinte:
<Ependency> <voundId> org.springframework.boot </frugid> <ArtifactId> Spring-boot-Starter-Web </ArtifactId> <Versão> 1.5.9.Release </sistER> </dependency> <pendence> <purbroud> org.springframework.boot </c//Groupid> <ArtifactId> Spring-Boot-Starter-Data-ELASTICSECHECH </TROTIFACTID> <Versão> 1.5.9.Release </sipers> </dependency>
Configuração do Application.Properties
spring.data.elasticsearch.repositionies.enabled = truespring.data.elasticsearch.cluster-nodes = 127.0.0.1/: 9300
Nota: 9300 é a porta do cliente Java. 9200 é uma interface que suporta HTTP RESTful.
Mais configurações:
spring.data.elticsearch.cluster-name Elasticsearch Nome do cluster. (Padrão: Elasticsearch)
spring.data.elticsearch.cluster-nodes Lista de endereços de nó de cluster, separados por vírgulas. Se não for especificado, inicie um nó do cliente.
spring.data.elticsearch.propertie é usado para configurar propriedades adicionais do cliente.
spring.data.elasticsearch.repositórios.enabled Habille o repositório Elasticsearch. (Padrão: true.)
Escrita de código
Classe de entidade
@Document (indexName = "userIndex", type = "user") classe pública o usuário implementa serializável { / ** * * / private estático final serialversionuid) = 1L; / ** Número*/ ID longo privado; / ** Nome*/ Nome de String Private; / ** idade*/ idade inteira privada; / ** Descrição*/ String privada Descrição; / ** tempo de criação*/ string privada createTM; // getter e setter omitido}Ao usar o SpringData, ele precisa definir o IndexName e digitar a classe de entidade. Se comparado aos bancos de dados tradicionais, é equivalente a bibliotecas e tabelas.
Deve -se notar que o IndexName e o Type devem estar em minúsculas !!!
Camada dao
interface pública userdao estende o elasticsearchRepository <usuário, long> {}A camada DAO é relativamente simples aqui, apenas herda a classe ElasticsearchRepository. Os principais métodos são salvar, excluir e pesquisar. O método de salvamento é como inserir e atualizar. Se não houver, será adicionado e, se houver um, será coberto. O método de exclusão é principalmente para excluir dados e indexar bibliotecas. Quanto à pesquisa, é uma consulta, incluindo algumas consultas comumente usadas, como paginação, pesos, etc.
Camada de serviço
@ServicePublic Class UserServiceImpl implementa UserService {@AUTOWIRED PRIVADO UserDAO Userdao; @Override public boolean Insert (usuário do usuário) {boolean falg = false; tente {userdao.save (usuário); falg = true; } catch (Exceção e) {e.printStackTrace (); } retornar FALG; } @Override Public List <suser> Pesquise (String SearchContent) {querystringQueryBuilder Builder = new QuerystringQueryBuilder (SearchContent); System.out.println ("declaração de consulta:"+construtor); Iterable <suser> searchResult = userdao.search (construtor); Iterator <suser> iterator = searchResult.iterator (); List <suser> list = new ArrayList <suser> (); while (iterator.hasnext ()) {list.add (iterator.Next ()); } Lista de retorno; } @Override Public List <Usuário> SearchUser (número inteiro pagenumber, Pagesize inteiro, string searchContent) {// parâmetros de paginação pagaable pagable = new PageRequest (pagenumber, PageSize); WerystringQueryBuilder Builder = new QuerystringQueryBuilder (SearchContent); SearchQuery SearchQuery = new NativearchQueryBuilder (). Compagável (pagável) .WithQuery (construtor) .build (); System.out.println ("declaração de consulta:" + SearchQuery.getQuery (). ToString ()); Página <suser> searchpageSults = userdao.search (searchQuery); return SearchPageSults.getContent (); } @Override Public List <Usous> SearchUserByWeight (String SearchContent) {// Query de acordo com Weights FunctionsCoreQuiller FunctionsCoreQueRyBuilder = QueryBuilders.functionsCoreQuerSers () .Add (QueryBuilders.BoolQuery (). ScorefunctionBuilders.weightFactorFunction (10)) .add (QueryBuilders.Boolquery (). System.out.println ("declaração de consulta:" + funçõescorequerybuilder.toString ()); Iterable <suser> searchResult = userdao.search (funçõesCoreQueryBuilder); Iterator <suser> iterator = searchResult.iterator (); List <suser> list = new ArrayList <suser> (); while (iterator.hasnext ()) {list.add (iterator.Next ()); } Lista de retorno; }}Aqui eu simplesmente escrevi vários métodos, o método principal é a consulta. As consultas incluem pesquisa de texto completo, consulta de paginação e consulta de peso. O que precisa ser explicado é a consulta de peso. Quanto maior a pontuação do peso, maior o resultado da consulta. Se nenhuma pontuação estiver definida para outros dados, sua pontuação padrão será 1. Se você não deseja consultar essas instruções, basta usar o setMinscore para defini -lo como maior que 1.
Teste de código
Chame a interface para adicionar dados
Novos dados:
POST http://localhost:8086/api/user{"id":1,"name":"Zhang San","age":20,"description":"Zhang San is a Java development engineer","createtm":"2018-4-25 11:07:42"}{"id":2,"name":"Li Si","age":24,"description":"Li Si é um engenheiro de teste "," createTM ":" 1980-2-15 19:01:32 "} {" id ": 3," name ":" Wang Wu "," Age ": 25," Descrição ":" Wang Wu é um engenheiro de operação e manutenção "," Createtm ":" 2016-8-21 06:32 "" Realizar uma consulta de texto completo
perguntar
http: // localhost: 8086/api/usuário? SearchContent = Engineer
retornar
[{"ID": 2, "Nome": "Li si", "Age": 14, "Descrição": "Li Si é um engenheiro de teste", "CreateTM": "1980-2-15 19:01:32"}, {"id": 1, "Nome": "Zhang San", "Age": 20, "Descrição": "Zh é "2018-4-25 11:07:42"}, {"id": 3, "nome": "Wang Wu", "Age": 25, "Descrição": "Wang Wu é um engenheiro de operação e manutenção", "createTM": "2016-8-21 06:11:32"}] Realizar uma consulta de paginação
perguntar
http: // localhost: 8086/api/user? pagenumber = 0 & Pagesize = 2 & SearchContent = Engineer
retornar
[{"ID": 2, "Nome": "Li si", "Age": 14, "Descrição": "Li Si é um engenheiro de teste"}, {"id": 1, "Name": "Zhang San", "Age": 20, "Descrição": "Zhang San é um engenheiro de desenvolvimento de Java"}] Realize a consulta de peso
perguntar
http: // localhost: 8086/api/user2? SearchContent = li si
retornar
[{"ID": 2, "Nome": "Li si", "Age": 24, "Descrição": "Li Si é um engenheiro de teste", "CreateTM": "1980-2-15 19:01:32"}]A declaração de impressão de consulta de peso:
Query statement:{{ "function_score" : { "functions" : [ { "filter" : { "bool" : { "bool" : { "should" : { "match" : { "name" : { "query" : "Li Si", "type" : "boolean" } } } } } } } }, "weight" : 10.0 }, { "filter" : { "bool": {"deve": {"match": {"description": {"Query": "li si", "tipo": "boolean"}}}}}}, "peso": 100.0}], "min_score": 2.0}}}}NOTA: No teste, como o peso mínimo do setMinscore está definido para ser dividido em 2, dados irrelevantes não serão exibidos. Se você deseja exibi -lo, basta removê -lo no código.
Depois de adicionar novos dados, você pode entrar: http: // localhost: 9200/_plugin/head/no navegador
Em seguida, clique em consulta básica para visualizar os dados adicionados. Se você deseja usar a consulta de declaração, pode colar a declaração de consulta impressa pelo console no programa na interface de consulta para consulta!
Nota: instalei o Elasticsearch aqui no Windows e instalei a cabeça do plug -in ES. As etapas específicas de instalação estão no final do artigo.
Além do SpringData, na verdade existem outros métodos para operar o Elasticsearch.
Por exemplo, use a API nativa do Elasticsearch e use a classe TransportClient para implementá -la.
Ou use -o para encapsular na primavera, basta injetar o feijão na camada de serviço.
Exemplo:
@Autowired ElasticsearchTemplate ElasticsearchTemplate;
No entanto, os métodos acima têm suas limitações, ou seja, como a versão do Elasticsearch é alterada, a API Java relevante também está se ajustando constantemente, ou seja, depois que a versão do servidor do Elasticsearch for alterada, o código do cliente pode precisar ser reescrito.
Portanto, introduz uma ferramenta de terceiros muito útil. Ele encapsula o Elasticsearch e preenche a lacuna no cliente de interface do Elasticsearch HTTPrest. É adequado para versões Elasticsearch 2.x ou acima, e não há necessidade de alterar o código devido à mudança da versão do Elasticsearch Server!
Jestclient
Primeiro, adicione as seguintes dependências no Maven:
<Depencency> <voundid> io.searchbox </foupid> <stifactId> jest </stifactId> <versão> 5.3.3 </versão> </dependency>
Em seguida, escreva o código de teste relevante.
Os comentários no código devem estar muito completos, então não falarei muito sobre o código aqui.
importar java.util.ArrayList; importar java.util.list; importar org.elasticsearch.index.Query.QueryBuilders; importar org.elasticsearch.search.builder.searchsourcebuilder; import com.pancm.pojo.user; importação io.searchbox.client; io.searchbox.client.JestClientFactory; importar io.searchbox.client.jestresult; importar io.searchbox.client.config.httpclientConfig; importação io.searchbox.core.bulk; importação io.search.core.bulkResult; importar io.searchBox.Core.DulkResult; import ioo.searchBox.Core.DulkResult; import ioo.searchBox.Core.DulkResult; import ioo.searchBox.Core.DulkResult; importar.core.bulk; import io.search.ore.ete.dulkResult; io.searchbox.core.documentResult; importar io.searchbox.core.index; importar io.searchbox.core.search; importar io.searchbox.indices.createIndiploxoxoxoxoxox.Imping.Mapping.SearchBoxBox.Indices.DeleteIndEx; importO.earchBoxoxox.Indices.Mapping.Mapping.Mapting.Mapting.Indices.DeleteIndEx; importO.earchBoxBox.Imaps.Mapping; JestTest {private estático JestClient JestClient; String estática privada indexName = "UserIndex"; // private static string indexname = "userIndex2"; string estática privada typename = "user"; Elastips de sequência estática privada = "http://192.169.2.98:9200"; // elastics de sequência estática privada = "http://127.0.0.1:9200"; public static void main (string [] args) lança exceção {jestclient = getJestClient (); insertBatch (); serach1 (); serach2 (); serach3 (); jestClient.Close (); } private estático jestclient getJestClient () {jestClientFactory Factory = new JestClientFactory (); Factory.SethttpClientConfig (novo httpclientConfig.builder (Elastips) .ConnTimeout (60000) .readTimeout (60000) .multithread (true) .build ()); retornar factory.getObject (); } public static void insertBatch () {list <ject> objs = new ArrayList <ject> (); objs.add (novo usuário (1L, "Zhang San", 20, "Zhang San é um engenheiro de desenvolvimento Java", "2018-4-25 11:07:42"); objs.add (novo usuário (2L, "li si", 24, "li si é um engenheiro de teste", "1980-2-15 19:01:32")); objs.add (novo usuário (3L, "Wang Wu", 25, "Wang Wu é um engenheiro de operação e manutenção", "2016-8-21 06:11:32"); resultado booleano = false; tente {resultado = insertBatch (jestclient, indexName, typename, objs); } catch (Exceção e) {e.printStackTrace (); } System.out.println ("lote novo:"+resultado); } / *** Pesquisa de texto completo* / public static void serach1 () {string query = "engenheiro"; tente {searchSourcebuilder searchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (QueryBuilders.QueryStringQuery (Query)); // Página Configuração da pesquisa de pesquisaBuilder.From (0) .Size (2); System.out.println ("Declaração de consulta de pesquisa de texto completo:"+searchSourceBuilder.toString ()); System.out.println ("Pesquisa de texto completo retorna o resultado:"+Pesquisa (JestClient, IndexName, Typename, SearchSourceBuilder.toString ())); } catch (Exceção e) {e.printStackTrace (); }} / *** pesquisa exata* / public static void serach2 () {try {searchSourceBuilder searchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (QueryBuilders.termQuery ("Age", 24)); System.out.println ("Declaração exata da consulta de pesquisa:"+searchSourceBuilder.toString ()); System.out.println ("A pesquisa exata retorna o resultado:"+pesquisa (jestclient, indexName, typename, SearchSourceBuilder.toString ())); } catch (Exceção e) {e.printStackTrace (); }} / *** Pesquisa de intervalo* / public static void serach3 () {string cremeTM = "createTM"; String de = "2016-8-21 06:11:32"; String para = "2018-8-21 06:11:32"; tente {searchSourcebuilder searchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (QueryBuilders.RangeQuery (createTM) .gte (de) .lte (to)); System.out.println ("Declaração de pesquisa de intervalo:"+SearchSourceBuilder.toString ()); System.out.println ("A pesquisa de intervalo retorna o resultado:"+pesquisa (JestClient, IndexName, Typename, SearchSourceBuilder.toString ())); } catch (Exceção e) {e.printStackTrace (); }} / ** * Criar índice * @param indexName * @return * @throws Exceção * / public boolean createIndex (jestclient jestclient, string indexname) lança exceção {jestresult jr = jestclient.execute (novo createIndex.builder (indexname) .build ();); return jr.issucededed (); } /** * New data* @param indexName * @param typeName * @param source * @return * @throws Exception */ public boolean insert(JestClient jestClient,String indexName, String typeName, String source) throws Exception { PutMapping putMapping = new PutMapping.Builder(indexName, typeName, source).build(); Jestresult jr = jestclient.execute (putmapping); return jr.issucededed (); } / ** * Dados de consulta * @param indexName * @param typename * @return * @throws exceção * / public static string getIndexMapping (jestclient jestclient, string indexName, string typename) lança exceção {getMapping getMapping = new getMapping.builder (). Jestresult jr = jestclient.execute (getMapping); return jr.getjSonstring (); } / ** * Adicione dados em lotes * @param indexName * @param typeName * @param objs * @return * @throws Exceção * / public estático boolean insertbatch (jestclient jestclient, string indexname, string typename, list <ject> objs) throws Exception {bulk.builder Bulk.Builder (). DefaultIndex (indexName) .DefaultType (Typename); for (objeto obj: objs) {index Index = new index.builder (obj) .build (); Bulk.addaction (índice); } BulkResult Br = JestClient.execute (Bulk.build ()); return b.issucededed (); } / ** * Pesquisa de texto completo * @param indexName * @param typename * @param Query * @return * @throws Exception * / public static string search (jestclient jestclient, string indexName, string tipename, string query) lança Exception {search = new search.builder (consultem). Jestresult jr = jestclient.execute (pesquisa); // system.out.println ("-"+jr.getjSonstring ()); // System.out.println ("-"+jr.getSourceasObject (user.class)); return jr.getSourceasString (); } / ** * Excluir índice * @param indexName * @return * @throws Exceção * / public boolean Delete (jestclient jestclient, string indexName) lança exceção {jestresult jr = jestclient.execute (new DeleteIndex.builder (indexname) .build ()); return jr.issucededed (); } / ** * Exclua dados * @param indexName * @param typeName * @param id * @return * @throws exceção * / public boolean delete (jestclient jestclient, string indexName, string typename, string id) lança exceção {documentResult dr = jestres DELETE.Builder (ID) .Index (IndexName) .Type (typename) .build ()); devolver o Dr.issucededed (); }Nota: Antes de testar, vamos primeiro explicar que a versão Elasticsearch instalada no sistema Windows local é 2.3.5, e a versão Elasticsearch instalada no servidor Linux é 6.2.
Resultados do teste
Pesquisa completa de texto
Declaração de consulta de busca de texto completo: {"de": 0, "size": 2, "Query": {"Query_string": {"Query": "Engineer"}}} Pesquisa de texto completo retorna resultado: {"id": 1, "nome": "zhang san", "idade": 20, "descrição" "" zh "zh" zhan: "Nome": "Zhang San", "idade": 20, "descrição" ":" Engenheiro "," CreateTM ":" 2018-4-25 11:07:42 "}, {" id ": 2," nome ":" Li si "," Age ": 24," Descrição ":" Li Si é um engenheiro de teste "," createTM ":" 1980-2-15 19:01:32 "}}"}Pesquisa de correspondência
Declaração precisa da Query: {"Query": {"termo": {"Age": 24}}} Pesquisa precisa retorna resultado: {"id": 2, "nome": "li si", "idade": 24, "descrição": "li si é um engenheiro de teste", "Createtm": "1980-2-15 19:012:3:"Pesquisa de intervalo de tempo
Declaração de pesquisa de intervalo: {"Query": {"range": {"createTM": {"de": "2016-8-21 06:11:32", "para": "2018-8-21 06:11:11:32", "include_lower": true, "include_upper": true}}}}} San "," Age ": 20," Descrição ":" Zhang San é um engenheiro de desenvolvimento Java "," CreateTM ":" 2018-4-25 11:07:42 "}Depois de adicionar novos dados, podemos ir ao Linux Kibana para realizar consultas relacionadas, e os resultados da consulta são os seguintes:
Nota: Kibana é um software de código aberto em alces. O Kibana fornece interfaces da Web amigáveis ao Log Analysis para Logstash e Elasticsearch para ajudar a resumir, analisar e pesquisar registros de dados importantes.
Os resultados retornados pelo teste no código acima estão alinhados com nossas expectativas. Entre eles, apenas uma pequena parte do brincadeira é usada. Para mais uso, você pode verificar a documentação oficial do JestClient.
Instale o Elasticsearch no Windows
1. Preparação de documentos
Endereço para download: https://www.elastic.co/downloads
Selecione a versão relacionada ao Elasticsearch e, em seguida, selecione o Nome do Sufixo File para baixar e descompacte -o após o download.
2. Iniciar o Elasticsearch
Vá para o diretório da bin e execute elasticsearch.bat
Em seguida, digite: localhost: 9200 na navegação
Exibir com sucesso a interface significa sucesso!
3. Instale o plug-in es
Instalação da cabeça da interface de gerenciamento da web
Digite o diretório da bin, abra CMD e insira a interface do DOS
Digite: plugin install mobz/elasticsearch-head
Fazer um download
Após o download bem -sucedido, digite: http: // localhost: 9200/_plugin/head/
Se a interface for exibida, a instalação será bem -sucedida!
4. Serviço de registro
Digite o diretório da bin, abra CMD e insira a interface do DOS
Digitar:
Service.bat installService.bat Start
Após o sucesso, entre
Services.msc
Salte para a interface de serviço para visualizar diretamente o status de execução do ES!
outro
Elasticsearch Official do site API Endereço:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html
Endereço JestClientGithub:
https://github.com/searchbox-io/jest (download local)
Coloquei o projeto no Github.
https://github.com/xuwujing/springboot (download local)
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.