搭建ES项目、使用java代码。可选的客户端有RestHighLevelClient、Spring Data Elasticsearch和Jest,本章将用一个搜索需求分别进行介绍。
1.1 Kibana客户端简介
Kibana是ELK家族中一个开源、免费的可视化数据搜索和分析平台。借助Kibana,用户不需要编码就可以将ES中分析的结果进行可视化呈现,如以常用的饼图、柱状图和时序图等方式呈现。除了可视化数据分析功能,Kibana还提供了Dev Tools,它是一款可以与ES进行交互式请求的工具,可以借助它进行DSL调试。限于篇幅,本节只介绍Kibana搭配单机版ES的配置方法
1.2 Kibana安装
注意:最好保持和es版本一致。
下载地址:https://www.elastic.co/cn/downloads/kibana 版本直接下载:https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-windows-x86_64.zip
- 下载完成直接解压
- 修改kibana文件夹下config/kibana.yml 把es的访问地址给写上 elasticsearch.hosts: [“http://localhost:9200”]
- 访问地址 http:127.0.0.1:5601
- 点击Dev Tools 目前的工具包含 1. Console:提供ES Rest形式交互的控制台2. Search Profiler:可以分析ES响应某一请求的耗时3. GROK DeBugger:提供GROK语言的调试器,联合使用logstash上传数据时,用作调试分割文本的表达式4. Painless Lab:提供Painless语言的调试器,用户在自定义排序脚本代码时可以使用
- 通过Kibana客户查询数据 1.
2. Java客户端简介
ES 和客户端的通信是根据Http来通信的。用户可以通过任意语言来进行通信。例如:java、Python等。java语言已经支持了很多的API只要拿来使用即可。
2.1 创建SpringBoot项目 导入es相关联的jar包
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.7-SNAPSHOT</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.xiaobai</groupId><artifactId>es</artifactId><version>0.0.1-SNAPSHOT</version><name>es</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.10.2</version></dependency><!--ES依赖--><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.10.2</version></dependency><!-- springBoot-data-Es 依赖--><!-- <dependency>--><!-- <groupId>org.springframework.boot</groupId>--><!-- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>--><!-- </dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
2.2 application.yml
elasticsearch:rest:hosts: 127.0.0.1:9200
2.3 创建ES client端Bean
- 无安全验证玩法
packagecom.example.xiaobai.es.resthightlevel;importorg.apache.http.HttpHost;importorg.elasticsearch.client.RestClient;importorg.elasticsearch.client.RestHighLevelClient;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.Arrays;importjava.util.Objects;@ConfigurationpublicclassEsClient{@Value("${elasticsearch.rest.hosts:}")//读取ES主机+端口配置privateString hosts;@Bean(value ="restHighLevelClient")publicRestHighLevelClientinitSimpleClient(){//根据配置文件配置HttpHost数组HttpHost[] httpHosts =Arrays.stream(hosts.split(",")).map(
host ->{//分隔ES服务器的IP和端口String[] hostParts = host.split(":");String hostName = hostParts[0];int port =Integer.parseInt(hostParts[1]);returnnewHttpHost(hostName, port,HttpHost.DEFAULT_SCHEME_NAME);}).filter(Objects::nonNull).toArray(HttpHost[]::new);//构建客户端returnnewRestHighLevelClient(RestClient.builder(httpHosts));}}
- 有安全验证玩法(生产)
@Bean(value ="restHighLevelClient")publicRestHighLevelClientinitSimpleClient1(){//根据配置文件配置HttpHost数组HttpHost[] httpHosts =Arrays.stream(hosts.split(",")).map(
host ->{//分隔ES服务器的IP和端口String[] hostParts = host.split(":");String hostName = hostParts[0];int port =Integer.parseInt(hostParts[1]);returnnewHttpHost(hostName, port,HttpHost.DEFAULT_SCHEME_NAME);}).filter(Objects::nonNull).toArray(HttpHost[]::new);// 生成凭证finalBasicCredentialsProvider basicCredentialsProvider =newBasicCredentialsProvider();
basicCredentialsProvider.setCredentials(AuthScope.ANY,newUsernamePasswordCredentials(esUser,esPassword));//构建客户端returnnewRestHighLevelClient(RestClient.builder(httpHosts).setHttpClientConfigCallback(newRestClientBuilder.HttpClientConfigCallback(){@OverridepublicHttpAsyncClientBuildercustomizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder){return httpAsyncClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider);}}));}
2.4 创建创建酒店对象pojo
packagecom.xiaobai.es.pojo;importlombok.Data;@DatapublicclassHotel{/**
* 对应文档id
*/privateString id;/**
* 索引名称
*/privateString index;/**
* 分数
*/privateFloat score;/**
* 酒店 名称
*/privateString title;/**
* 酒店城市
*/privateString city;/**
* 酒店价格
*/privateDouble price;}
2.5 创建service类
packagecom.xiaobai.es.service;importcom.xiaobai.es.pojo.Hotel;importorg.elasticsearch.action.search.SearchRequest;importorg.elasticsearch.action.search.SearchResponse;importorg.elasticsearch.client.RequestOptions;importorg.elasticsearch.client.RestHighLevelClient;importorg.elasticsearch.index.query.QueryBuilders;importorg.elasticsearch.rest.RestStatus;importorg.elasticsearch.search.SearchHit;importorg.elasticsearch.search.SearchHits;importorg.elasticsearch.search.builder.SearchSourceBuilder;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;@ServicepublicclassEsService{@ResourceprivateRestHighLevelClient restHighLevelClient;privatefinalstaticString INDEX_NAME ="hoteld";publicList<Hotel>getHotelFromTitle(String keyword){// 客户端请求 创建请求对象 传入索引名称SearchRequest searchRequest =newSearchRequest(INDEX_NAME);// 构建查询条件对象SearchSourceBuilder searchSourceBuilder =newSearchSourceBuilder();// 书写查询语句
searchSourceBuilder.query(QueryBuilders.matchQuery("title",keyword));// 把查询语句设置给请求对象
searchRequest.source(searchSourceBuilder);List<Hotel> hotels =newArrayList<>();// 查询try{SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);RestStatus status = searchResponse.status();if(status !=RestStatus.OK){return hotels;}SearchHits hits = searchResponse.getHits();for(SearchHit hit : hits){Hotel hotel =newHotel();
hotel.setId(hit.getId());
hotel.setIndex(hit.getIndex());
hotel.setScore(hit.getScore());Map<String,Object> sourceAsMap = hit.getSourceAsMap();
hotel.setTitle((String) sourceAsMap.get("title"));
hotel.setCity((String) sourceAsMap.get("city"));
hotel.setPrice((Double) sourceAsMap.get("price"));
hotels.add(hotel);}}catch(IOException e){
e.printStackTrace();}return hotels;}}
- 首先创建SearchRequest对象 传入要查询的索引名称hoteld。
- 创建承载的查询条件对象SearchSourceBuilder 1. 传入QueryBuilder对象传入查询条件对象。本次是根据九点名称来模糊查询。
- 请求对象设置查询条件对象。 searchRequest.source(searchSourceBuilder);
- 通过restHighLevelClient查询。 1. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);2. searchResponse.getHits() 返回了所有查询结果的封装数据。3. 遍历Hits 可得到Hit。这里面可以获取到对应的索引名称、分数、文档id等4. hit.getSourceAsMap()把文档内容转换成map的方式便于获取。但是可能会有null指针的情况。
2.6 elasticsearch-rest-high-level-client
- 这种方式配置起来比较复杂。
- 每次查询的时候都是根据rest http的方式去调用es服务。每次都需要建立链接
- 查询信息和转换数据比较麻烦
3. Spring-Data-Elasticsearch 方式
spring-data-elasticsearch是和springBoot中的一套组件。可以和es服务保持长链接,不需要每次查询的时候需要建立网络链接了。并且可以通过Repository接口自动实现,可以通过方法名的语义实现查询功能。而且查询到数据后可以直接封装到自定义pojo中。方便后续对数据的二次加工。
3.1 创建SpringBoot客户端
3.1.1导入相关jar包
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.8</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.sping.data</groupId><artifactId>springdata</artifactId><version>0.0.1-SNAPSHOT</version><name>springdata</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
3.1.2 配置application.yml
spring:elasticsearch:rest:uris: http://127.0.0.1:9200username: elastic
password: password
如果想要配置多个节点只需要uris 配置多个ip即可。中间用逗号分割。
3.1.3 使用spring-data-elasticsearchl来根据"再来"查询符合的酒店
3.1.3.1创建pojo类
@Data@Document(indexName ="hoteld")publicclassHotel1{@IdprivateString id;privateString title;privateString city;privateDouble price;}
@Id 代表是主键id 级文档id
3.1.3.2 创建Repository对象
/**
* @author liruiqing
*/publicinterfaceEsRepositoryextendsCrudRepository<Hotel1,String>{/**
* 根据 title 查询符合的酒店
* @param title
* @return
*/List<Hotel1>findByTitleLike(String title);}
以方法名语义的方式实现查询数据。
需要继承CrudRepository<o1,o2> o1 为pojo类 o2为文档id类型
3.1.3.3 service类
@ServicepublicclassEsService{@AutowiredprivateEsRepository esRepository;publicList<Hotel1>findByTitleLike(String keyword){List<Hotel1> byTitleLike = esRepository.findByTitleLike(keyword);return byTitleLike;}}
3.1.3.4 controller类
@RestControllerpublicclassTestController{@AutowiredprivateEsService esService;@RequestMapping("/test")publicStringgetHotelStr(){List<Hotel1> hotels = esService.findByTitleLike("再来");if(hotels.isEmpty()){return"no data";}return hotels.toString();}}
4. Jest客户端搜索文档
Jest是为springBoot项目是低版本时做兼容时用到的,如果SpringBoot的版本过高的话application.yml中配置信息已经不生效了,被移除了。下面的版本是可以使用的。
4.1 配置项
4.1.1 导入相关jar包
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.8.RELEASE</version><relativePath/><!-- lookup parent from repository springboot版本--></parent><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Jest依赖--><dependency><groupId>io.searchbox</groupId><artifactId>jest</artifactId><version>6.3.1</version></dependency><!--简化开发组件Lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--ES依赖--><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.10.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>7.17.8</version><scope>compile</scope></dependency></dependencies>
4.1.2 配置application.yml
spring:elasticsearch:jest:uris: http://127.0.0.1:9200username: elastic
password: password
server:port:8082
4.2 实现
4.2.1 Pojo类
@DatapublicclassHotel{@JestId// 文档idprivateString id;privateString title;privateString city;privateDouble price;}
4.2.2 service类
@ServicepublicclassEsService{@ResourceprivateJestClient jestClient;publicList<Hotel>findByTitleLike(String keyword){// 创建sql语句对象 本次为查询语句MatchQueryBuilder matchQuery =QueryBuilders.matchQuery("title", keyword);// 设置查询builder对象 并把查询对象设置进去SearchSourceBuilder searchSourceBuilder =newSearchSourceBuilder();
searchSourceBuilder.query(matchQuery);// 调用search.Builder把查询的builder对象字符串给设置进去 addIndex是索引名称Search search =newSearch.Builder(searchSourceBuilder.toString()).addIndex("hoteld").build();try{// 使用jestClient.execute()方法获取searchResult数据对象 并把返回的数据集通过getSourceAsObjectList转换为集合 SearchResult searchResult = jestClient.execute(search);if(searchResult.isSucceeded()){List<Hotel> sourceAsObjectList = searchResult.getSourceAsObjectList(Hotel.class);return sourceAsObjectList;}}catch(IOException e){
e.printStackTrace();}returnnull;}}
4.2.3 Controller类
@RestControllerpublicclassTestController{@AutowiredprivateEsService esService;@RequestMapping("/test")publicStringfindByTitleLike(){List<Hotel> hotels = esService.findByTitleLike("再来");if(hotels ==null|| hotels.isEmpty()){return"no data";}return hotels.toString();}}
版权归原作者 小白不很白 所有, 如有侵权,请联系我们删除。