• 【ElasticSearch】 ElasticSearch Java客户端(十一)


    Java客户端

      在Elasticsearch中,为java提供了2种客户端,一种是REST风格的客户端,另一种是Java API的客户端。

      官网:https://www.elastic.co/guide/en/elasticsearch/client/index.html

      

    REST客户端

      Elasticsearch提供了2种REST客户端,一种是低级客户端,一种是高级客户端。

      Java Low Level REST Client: 官方提供的低级客户端。该客户端通过http来连接Elasticsearch集群。用户在使 用该客户端时需要将请求数据手动拼接成Elasticsearch所需JSON格式进行发送,收到响应时同样也需要将返回 的JSON数据手动封装成对象。虽然麻烦,不过该客户端兼容所有的Elasticsearch版本。

      Java High Level REST Client: 官方提供的高级客户端。该客户端基于低级客户端实现,它提供了很多便捷的 API来解决低级客户端需要手动转换数据格式的问题。

      示例数据

     1 POST /house/_bulk
     2 
     3 {"index":{"_index":"house"}}
     4 {"id":"1001","title":"整租 · 南丹大楼 1居室 7500","price":"7500"} 
     5 {"index":{"_index":"house"}} 
     6 {"id":"1002","title":"陆家嘴板块,精装设计一室一厅,可拎包入住诚意租。","price":"8500"} 
     7 {"index":{"_index":"house"}}
     8 {"id":"1003","title":"整租 · 健安坊 1居室 4050","price":"7500"} 
     9 {"index":{"_index":"house"}}
    10 {"id":"1004","title":"整租 · 中凯城市之光+视野开阔+景色秀丽+拎包入住","price":"6500"} 
    11 {"index":{"_index":"house"}}
    12 {"id":"1005","title":"整租 · 南京西路品质小区 21213三轨交汇 配套齐* 拎包入住","price":"6000"} 
    13 {"index":{"_index":"house"}}
    14 {"id":"1006","title":"祥康里 简约风格 *南户型 拎包入住 看房随时","price":"7000"}

    REST低级客户端

      测试elasticsearch版本是:7.6.1

      1、创建工程test-springboot-elasticsearch,引入依赖

    1 <!-- elasticsearch -->
    2 <dependency>
    3     <groupId>org.elasticsearch.client</groupId>
    4     <artifactId>elasticsearch-rest-client</artifactId>
    5     <version>7.6.1</version>
    6 </dependency>

        完整依赖如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0"
     3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5     <modelVersion>4.0.0</modelVersion>
     6 
     7     <groupId>com.test</groupId>
     8     <artifactId>test-springboot-es</artifactId>
     9     <version>1.0-SNAPSHOT</version>
    10 
    11     <parent>
    12         <groupId>org.springframework.boot</groupId>
    13         <artifactId>spring-boot-starter-parent</artifactId>
    14         <version>2.2.5.RELEASE</version>
    15     </parent>
    16 
    17     <properties>
    18         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    19         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    20         <java.version>1.8</java.version>
    21     </properties>
    22 
    23     <dependencies>
    24 
    25         <dependency>
    26             <groupId>org.springframework.boot</groupId>
    27             <artifactId>spring-boot-starter-web</artifactId>
    28         </dependency>
    29 
    30         <dependency>
    31             <groupId>org.elasticsearch.client</groupId>
    32             <artifactId>elasticsearch-rest-client</artifactId>
    33             <version>7.6.1</version>
    34         </dependency>
    35 
    36 
    37         <dependency>
    38             <groupId>org.springframework.boot</groupId>
    39             <artifactId>spring-boot-starter-test</artifactId>
    40             <scope>test</scope>
    41         </dependency>
    42 
    43     </dependencies>
    44 
    45 
    46     <!-- SpringBoot打包插件,可以将代码打包成一个可执行的jar包 -->
    47     <build>
    48         <plugins>
    49             <plugin>
    50                 <groupId>org.springframework.boot</groupId>
    51                 <artifactId>spring-boot-maven-plugin</artifactId>
    52             </plugin>
    53         </plugins>
    54     </build>
    55 </project>
    View Code

      2、编写测试用例

     1 package com.test.springboot.es;
     2 
     3 import com.fasterxml.jackson.databind.ObjectMapper;
     4 import org.apache.http.HttpHost;
     5 import org.apache.http.util.EntityUtils;
     6 import org.elasticsearch.client.*;
     7 import org.junit.After;
     8 import org.junit.Before;
     9 import org.junit.Test;
    10 
    11 import java.io.IOException;
    12 import java.util.HashMap;
    13 import java.util.Map;
    14 
    15 public class TestLowRestClient {
    16 
    17     private static final ObjectMapper MAPPER = new ObjectMapper();
    18     private RestClient restClient;
    19 
    20     @Before
    21     public void init() {
    22         RestClientBuilder restClientBuilder = RestClient.builder(
    23                 new HttpHost("127.0.0.1", 19201, "http"),
    24                 new HttpHost("127.0.0.1", 19202, "http"),
    25                 new HttpHost("127.0.0.1", 19203, "http"));
    26         restClientBuilder.setFailureListener(new RestClient.FailureListener() {
    27             @Override
    28             public void onFailure(Node node) {
    29                 System.out.println("出错了 -> " + node);
    30             }
    31         });
    32         this.restClient = restClientBuilder.build();
    33     }
    34 
    35     @After
    36     public void after() throws IOException {
    37         restClient.close();
    38     }
    39 
    40     // 查询集群状态
    41     @Test
    42     public void testGetInfo() throws IOException {
    43         Request request = new Request("GET", "/_cluster/state");
    44         request.addParameter("pretty", "true");
    45         Response response = this.restClient.performRequest(request);
    46         System.out.println(response.getStatusLine());
    47         System.out.println(EntityUtils.toString(response.getEntity()));
    48     }
    49 
    50 
    51     // 新增数据
    52     @Test
    53     public void testCreateData() throws IOException {
    54         Request request = new Request("POST", "/house/_doc");
    55         Map<String, Object> data = new HashMap<>();
    56         data.put("id", "2001");
    57         data.put("title", "张江高科");
    58         data.put("price", "3500");
    59         request.setJsonEntity(MAPPER.writeValueAsString(data));
    60         Response response = this.restClient.performRequest(request);
    61         System.out.println(response.getStatusLine());
    62         System.out.println(EntityUtils.toString(response.getEntity()));
    63     }
    64 
    65 
    66     // 根据id查询数据
    67     @Test
    68     public void testQueryData() throws IOException {
    69         Request request = new Request("GET", "/house/_doc/i7I4snIB-J-F9-0D3D6H");
    70         Response response = this.restClient.performRequest(request);
    71         System.out.println(response.getStatusLine());
    72         System.out.println(EntityUtils.toString(response.getEntity()));
    73     }
    74 
    75     // 搜索数据
    76     @Test
    77     public void testSearchData() throws IOException {
    78         Request request = new Request("POST", "/house/_search");
    79         String searchJson = "{"query": {"match": {"title": "拎包入住"}}}";
    80         request.setJsonEntity(searchJson);
    81         request.addParameter("pretty", "true");
    82         Response response = this.restClient.performRequest(request);
    83         System.out.println(response.getStatusLine());
    84         System.out.println(EntityUtils.toString(response.getEntity()));
    85     }
    86 
    87 } 

       3、测试

        分别测试以上方法,均能正常返回

      从使用中,可以看出,基本和我们使用RESTful api使用几乎是一致的。

    REST高级客户端

       1、在工程共新增高级客户端依赖

     1 <dependency>
     2     <groupId>org.elasticsearch.client</groupId>
     3     <artifactId>elasticsearch-rest-high-level-client</artifactId>
     4     <version>7.6.1</version>
     5     <exclusions>
     6         <exclusion>
     7             <groupId>org.elasticsearch</groupId>
     8             <artifactId>elasticsearch</artifactId>
     9         </exclusion>
    10     </exclusions>
    11 </dependency>
    12 <dependency>
    13     <groupId>org.elasticsearch</groupId>
    14     <artifactId>elasticsearch</artifactId>
    15     <version>7.6.1</version>
    16 </dependency>
    17 
    18 <dependency>
    19     <groupId>org.elasticsearch.client</groupId>
    20     <artifactId>elasticsearch-rest-client</artifactId>
    21     <version>7.6.1</version>
    22 </dependency>

      2、编写测试用例

      1 package com.test.springboot.es;
      2 
      3 import com.fasterxml.jackson.databind.ObjectMapper;
      4 import org.apache.http.HttpHost;
      5 import org.apache.http.util.EntityUtils;
      6 import org.elasticsearch.action.ActionListener;
      7 import org.elasticsearch.action.delete.DeleteRequest;
      8 import org.elasticsearch.action.delete.DeleteResponse;
      9 import org.elasticsearch.action.get.GetRequest;
     10 import org.elasticsearch.action.get.GetResponse;
     11 import org.elasticsearch.action.index.IndexRequest;
     12 import org.elasticsearch.action.index.IndexResponse;
     13 import org.elasticsearch.action.search.SearchRequest;
     14 import org.elasticsearch.action.search.SearchResponse;
     15 import org.elasticsearch.action.update.UpdateRequest;
     16 import org.elasticsearch.action.update.UpdateResponse;
     17 import org.elasticsearch.client.*;
     18 import org.elasticsearch.common.Strings;
     19 import org.elasticsearch.common.unit.TimeValue;
     20 import org.elasticsearch.index.query.QueryBuilders;
     21 import org.elasticsearch.search.SearchHit;
     22 import org.elasticsearch.search.SearchHits;
     23 import org.elasticsearch.search.builder.SearchSourceBuilder;
     24 import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
     25 import org.junit.After;
     26 import org.junit.Before;
     27 import org.junit.Test;
     28 
     29 import java.io.IOException;
     30 import java.util.HashMap;
     31 import java.util.Map;
     32 import java.util.concurrent.TimeUnit;
     33 
     34 public class TestHighRestClient {
     35 
     36     private static final ObjectMapper MAPPER = new ObjectMapper();
     37     private RestHighLevelClient restHighClient;
     38 
     39     @Before
     40     public void init() {
     41 
     42         RestClientBuilder restClientBuilder = RestClient.builder(
     43                 new HttpHost("127.0.0.1", 19201, "http"),
     44                 new HttpHost("127.0.0.1", 19202, "http"),
     45                 new HttpHost("127.0.0.1", 19203, "http"));
     46         restClientBuilder.setFailureListener(new RestClient.FailureListener() {
     47             @Override
     48             public void onFailure(Node node) {
     49                 System.out.println("出错了 -> " + node);
     50             }
     51         });
     52 
     53         this.restHighClient = new RestHighLevelClient(restClientBuilder);
     54     }
     55 
     56     @After
     57     public void after() throws IOException {
     58         restHighClient.close();
     59     }
     60 
     61     // 新增文档,同步操作
     62     @Test
     63     public void testCreate() throws Exception {
     64         Map<String, Object> data = new HashMap<>();
     65         data.put("id", "2002");
     66         data.put("title", "南京西路 拎包入住 一室一厅");
     67         data.put("price", "4500");
     68         IndexRequest indexRequest = new IndexRequest("house", "_doc").source(data);
     69         IndexResponse indexResponse = restHighClient.index(indexRequest, RequestOptions.DEFAULT);
     70         System.out.println("id->" + indexResponse.getId());
     71         System.out.println("index->" + indexResponse.getIndex());
     72         System.out.println("type->" + indexResponse.getType());
     73         System.out.println("version->" + indexResponse.getVersion());
     74         System.out.println("result->" + indexResponse.getResult());
     75         System.out.println("shardInfo->" + indexResponse.getShardInfo());
     76     }
     77 
     78     //  新增文档,异步操作
     79     @Test
     80     public void testCreateAsync() throws Exception {
     81         Map<String, Object> data = new HashMap<>();
     82         data.put("id", "2003");
     83         data.put("title", "南京东路 最新房源 二室一厅");
     84         data.put("price", "5500");
     85         IndexRequest indexRequest = new IndexRequest("house", "_doc").source(data);
     86         restHighClient.indexAsync(indexRequest, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
     87             @Override
     88             public void onResponse(IndexResponse indexResponse) {
     89                 System.out.println("id->" + indexResponse.getId());
     90                 System.out.println("index->" + indexResponse.getIndex());
     91                 System.out.println("type->" + indexResponse.getType());
     92                 System.out.println("version->" + indexResponse.getVersion());
     93                 System.out.println("result->" + indexResponse.getResult());
     94                 System.out.println("shardInfo->" + indexResponse.getShardInfo());
     95             }
     96 
     97             @Override
     98             public void onFailure(Exception e) {
     99                 System.out.println(e);
    100             }
    101         });
    102         System.out.println("ok");
    103         Thread.sleep(20000);
    104     }
    105 
    106     // 测试查询
    107     @Test
    108     public void testQuery() throws Exception {
    109         GetRequest getRequest = new GetRequest("house", "_doc",
    110                 "jLI5snIB-J-F9-0D8j7h");
    111         // 指定返回的字段
    112         String[] includes = new String[]{"title", "id"};
    113         String[] excludes = Strings.EMPTY_ARRAY;
    114         FetchSourceContext fetchSourceContext =
    115                 new FetchSourceContext(true, includes, excludes);
    116         getRequest.fetchSourceContext(fetchSourceContext);
    117         GetResponse response = restHighClient.get(getRequest, RequestOptions.DEFAULT);
    118         System.out.println("数据 -> " + response.getSource());
    119     }
    120 
    121 
    122     // 判断是否存在
    123     @Test
    124     public void testExists() throws Exception {
    125         GetRequest getRequest = new GetRequest("house", "_doc", "jLI5snIB-J-F9-0D8j7h"); // 不返回的字段
    126         // 不返回的字段
    127         getRequest.fetchSourceContext(new FetchSourceContext(false));
    128         boolean exists = restHighClient.exists(getRequest, RequestOptions.DEFAULT);
    129         System.out.println("exists -> " + exists);
    130     }
    131 
    132     // 删除数据
    133     @Test
    134     public void testDelete() throws Exception {
    135 
    136         DeleteRequest deleteRequest = new DeleteRequest("house", "_doc",
    137                 "jLI5snIB-J-F9-0D8j7h");
    138         DeleteResponse response = restHighClient.delete(deleteRequest,
    139                 RequestOptions.DEFAULT);
    140         System.out.println(response.status());// OK or NOT_FOUND
    141     }
    142 
    143     // 更新数据
    144     @Test
    145     public void testUpdate() throws Exception {
    146         UpdateRequest updateRequest = new UpdateRequest("house", "_doc",
    147                 "i7I4snIB-J-F9-0D3D6H");
    148         Map<String, Object> data = new HashMap<>();
    149         data.put("title", "张江高科2");
    150         data.put("price", "5000");
    151         updateRequest.doc(data);
    152         UpdateResponse response = restHighClient.update(updateRequest, RequestOptions.DEFAULT);
    153         System.out.println("version -> " + response.getVersion());
    154     }
    155 
    156 
    157     // 搜索数据
    158     @Test
    159     public void testSearch() throws Exception {
    160         SearchRequest searchRequest = new SearchRequest("house");
    161         searchRequest.types("_doc");
    162         SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    163         sourceBuilder.query(QueryBuilders.matchQuery("title", "拎包入住"));
    164         sourceBuilder.from(0);
    165         sourceBuilder.size(5);
    166         sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    167         searchRequest.source(sourceBuilder);
    168         SearchResponse search = restHighClient.search(searchRequest, RequestOptions.DEFAULT);
    169         System.out.println("搜索到 " + search.getHits().getTotalHits().value + " 条数据.");
    170         SearchHits hits = search.getHits();
    171         for (SearchHit hit : hits) {
    172             System.out.println(hit.getSourceAsString());
    173         }
    174     }
    175 }

    REST客户端与SpringBoot集成

      测试elasticsearch版本是:7.6.1

      集成原理:

        在SpringBoot自动装配类(RestClientAutoConfiguration.class)中,导入Rest客户端配置类(RestClientConfigurations)中的静态类

    1 @Configuration(proxyBeanMethods = false)
    2 @ConditionalOnClass(RestClient.class)
    3 @EnableConfigurationProperties(RestClientProperties.class)
    4 @Import({ RestClientConfigurations.RestClientBuilderConfiguration.class,
    5         RestClientConfigurations.RestHighLevelClientConfiguration.class,
    6         RestClientConfigurations.RestClientFallbackConfiguration.class })
    7 public class RestClientAutoConfiguration {
    8 
    9 }

        查看Rest客户端配置类(RestClientConfigurations)

     1 class RestClientConfigurations {
     2 
     3     ...
     4 
     5     @Configuration(proxyBeanMethods = false)
     6     @ConditionalOnClass(RestHighLevelClient.class)
     7     static class RestHighLevelClientConfiguration {
     8 
     9         // 高级客户端
    10         @Bean
    11         @ConditionalOnMissingBean
    12         RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
    13             return new RestHighLevelClient(restClientBuilder);
    14         }
    15 
    16         // 低级客户端
    17         @Bean
    18         @ConditionalOnMissingBean
    19         RestClient elasticsearchRestClient(RestClientBuilder builder,
    20                 ObjectProvider<RestHighLevelClient> restHighLevelClient) {
    21             RestHighLevelClient client = restHighLevelClient.getIfUnique();
    22             if (client != null) {
    23                 return client.getLowLevelClient();
    24             }
    25             return builder.build();
    26         }
    27 
    28     }
    29 
    30     ...
    31 
    32 }

        可以看到配置类中,自动配置类 ES低级客户端、ES高级客户端

      集成

      1、新建项目引入依赖,spring-boot-starter-data-elasticsearch

    1 <!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 -->
    2 <dependency>
    3     <groupId>org.springframework.boot</groupId>
    4     <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 
    5 </dependency>

        完整依赖如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0"
     3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5     <modelVersion>4.0.0</modelVersion>
     6 
     7     <groupId>com.test</groupId>
     8     <artifactId>test-springboot-es</artifactId>
     9     <version>1.0-SNAPSHOT</version>
    10 
    11     <parent>
    12         <groupId>org.springframework.boot</groupId>
    13         <artifactId>spring-boot-starter-parent</artifactId>
    14         <version>2.2.5.RELEASE</version>
    15     </parent>
    16 
    17     <properties>
    18 
    19         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    20         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    21         <java.version>1.8</java.version>
    22     </properties>
    23 
    24     <dependencies>
    25 
    26         <dependency>
    27             <groupId>org.springframework.boot</groupId>
    28             <artifactId>spring-boot-starter-web</artifactId>
    29         </dependency>
    30 
    31 
    32         <!-- SpringBoot默认使用SpringData ElasticSearch模块进行操作 -->
    33         <dependency>
    34             <groupId>org.springframework.boot</groupId>
    35             <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 
    36         </dependency>
    37         
    38         <dependency>
    39             <groupId>org.springframework.boot</groupId>
    40             <artifactId>spring-boot-starter-test</artifactId>
    41             <scope>test</scope>
    42         </dependency>
    43 
    44     </dependencies>
    45 
    46 
    47     <!-- SpringBoot打包插件,可以将代码打包成一个可执行的jar包 -->
    48     <build>
    49         <plugins>
    50             <plugin>
    51                 <groupId>org.springframework.boot</groupId>
    52                 <artifactId>spring-boot-maven-plugin</artifactId>
    53             </plugin>
    54         </plugins>
    55     </build>
    56 </project>
    View Code

       2、编写测试用例

     1 package com.test.springboot.es;
     2 
     3 
     4 import org.apache.http.util.EntityUtils;
     5 import org.elasticsearch.action.search.SearchRequest;
     6 import org.elasticsearch.action.search.SearchResponse;
     7 import org.elasticsearch.client.*;
     8 import org.elasticsearch.common.unit.TimeValue;
     9 import org.elasticsearch.index.query.QueryBuilders;
    10 import org.elasticsearch.search.SearchHit;
    11 import org.elasticsearch.search.SearchHits;
    12 import org.elasticsearch.search.builder.SearchSourceBuilder;
    13 import org.junit.Test;
    14 import org.junit.runner.RunWith;
    15 import org.springframework.beans.factory.annotation.Autowired;
    16 import org.springframework.boot.test.context.SpringBootTest;
    17 import org.springframework.test.context.junit4.SpringRunner;
    18 
    19 import java.io.IOException;
    20 import java.util.concurrent.TimeUnit;
    21 
    22 @RunWith(SpringRunner.class)
    23 @SpringBootTest
    24 public class TestSpringBootES {
    25 
    26     // 低级客户端
    27     @Autowired
    28     RestClient restClient;
    29 
    30     // 高级客户端
    31     @Autowired
    32     RestHighLevelClient restHighLevelClient;
    33 
    34     // 低级客户端搜索数据
    35     @Test
    36     public void testRestClientSearch() throws IOException {
    37         Request request = new Request("POST", "/house/_search");
    38         String searchJson = "{"query": {"match": {"title": "拎包入住"}}}";
    39         request.setJsonEntity(searchJson);
    40         request.addParameter("pretty", "true");
    41         Response response = restClient.performRequest(request);
    42         System.out.println(response.getStatusLine());
    43         System.out.println(EntityUtils.toString(response.getEntity()));
    44     }
    45 
    46     // 高级客户端搜索数据
    47     @Test
    48     public void testRestHighLevelClientSearch() throws Exception {
    49         SearchRequest searchRequest = new SearchRequest("house");
    50         SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    51         sourceBuilder.query(QueryBuilders.matchQuery("title", "拎包入住"));
    52         sourceBuilder.from(0);
    53         sourceBuilder.size(5);
    54         sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    55         searchRequest.source(sourceBuilder);
    56         SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    57         System.out.println("搜索到 " + search.getHits().getTotalHits() + " 条数据.");
    58         SearchHits hits = search.getHits();
    59         for (SearchHit hit : hits) {
    60             System.out.println(hit.getSourceAsString());
    61         }
    62     }
    63 }

      3、编辑application.yml文件

    1 spring:
    2   elasticsearch:
    3     rest:
    4       uris: http://127.0.0.1:9200

      4、测试验证, 测试方法皆运行成功,证明ES低级客户端、ES高级客户端皆有效

  • 相关阅读:
    【转】测试人员职业规划
    phantomjs处理alert、confirm弹窗
    linux搭建phantomjs+webdriver+testng+ant自动化工程
    linux搭建apache服务并修改默认路径
    linux环境vnc部署过程详解
    mongodb集群+分片部署(二)
    mongodb部署单节点(一)
    java javaScript实现遮罩层 动态加载
    感受
    JavaScript之中Array用法的一些技巧总结
  • 原文地址:https://www.cnblogs.com/h--d/p/13126879.html
Copyright © 2020-2023  润新知