• RestClient Java客户端


    一、什么是RestClient

    ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。

    官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

    二、RestClient操作索引库

    资源链接
    数据库数据:https://pan.baidu.com/s/1KC16E5Xpl_HsvHriGrfUkw
    提取码:GY66
    hotel-demo:https://pan.baidu.com/s/1MxVBdmeL4C3QhLlZrru8hA
    提取码:GY66

    数据库表数据:
    在这里插入图片描述

    CREATE TABLE `tb_hotel` (
      `id` bigint(20) NOT NULL COMMENT '酒店id',
      `name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',
      `address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',
      `price` int(10) NOT NULL COMMENT '酒店价格;例:329',
      `score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',
      `brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',
      `city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',
      `star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',
      `business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',
      `latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',
      `longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',
      `pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    tips

    ES中支持两种地理坐标数据类型:
    geo_point:由纬度(latitude)和经度(longitude)确定的一个点。
    例如:"32.8752345, 120.2981576"
    geo_shape:有多个geo_point组成的复杂几何图形。
    例如一条直线,"LINESTRING (-77.03653 38.897676, -77.009051 38.889939)"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们期望可以根据多个字段搜索,同时也期望搜索的效率较高(es在做搜索时只根据一个字段搜索显然效率更高)。字段拷贝可以使用copy_to属性将当前字段拷贝到指定字段。示例:

    "all": {
      "type": "text",
      "analyzer": "ik_max_word"
    },
    "brand": {
      "type": "keyword",
      "copy_to": "all"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    案例:利用JavaRestClient实现创建、删除索引库,判断索引库是否存在

    根据提供的酒店数据创建索引库,索引库名为hotel,mapping属性根据数据库结构定义。
    1、导入Demo案例
    2、分析数据结构,定义mapping属性

    mapping要考虑的问题:
    字段名、数据类型、是否参与搜索、是否分词、如果分词,分词器是什么?
    
    #  酒店的mapping
    
    ```sql
    PUT /hotel
    {
      "mappings": {
        "properties": {
          "id":{
            "type": "keyword"
          },
          "name":{
            "type": "text",
            "analyzer": "ik_max_word" , 
            "copy_to": "{all}"
          },
          "address":{
            "type": "keyword",
            "index": false
          },
          "price":{
            "type": "integer"
          },
          "score":{
            "type": "integer"
          },
          "brand":{
            "type":"keyword",
            "copy_to": "{all}"
          },
          "city":{
            "type":"keyword"
          },
          "starName":{
            "type": "keyword"
          },
          "business":{
            "type":"keyword",
            "copy_to": "{all}"
          },
          "latitude":{
            "type": "geo_point"
          },
          "location":{                     #将经纬度拼接在一起
            "type": "geo_point"
          },
          "pic":{
            "type":"keyword", 
            "index": false
          },
          "all":{
            "type": "text", 
            "analyzer": "ik_max_word"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    3、初始化JavaRestClient
    ① 引入es的RestHighLevelClient依赖:

     
            <dependency>
                <groupId>org.elasticsearch.clientgroupId>
                <artifactId>elasticsearch-rest-high-level-clientartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ② 因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本

    <properties>
            <java.version>1.8java.version>
            <elasticsearch.version>7.12.1elasticsearch.version>
        properties>
    
    • 1
    • 2
    • 3
    • 4

    ③ 初始化RestHighLevelClient:

    @SpringBootTest
    class HotelDemoApplicationTests {
        private RestHighLevelClient client;
        @BeforeEach
         //   初始化RestHighLevelClient
        void setUp() {
            this.client=new RestHighLevelClient(RestClient.builder(
               HttpHost.create("http://192.168.197.140:9200")));      //  若是集群,可指定多个
        }
         @Test
        void testInit() {
            System.out.println(client);
        }
        @AfterEach
        //  销毁
        void tearDown() throws IOException {
            this.client.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4、利用JavaRestClient创建索引库

    映射模板工具类

    package com.GY.hotel.constants;
    
    public class HotelConstants {
    
    
        public static final String MAPPING_TEMPLATE ="{\n " +
                "  \"mappings\": {\n "+
                "   \"properties\": {\n "+
                "      \"id\":{\n "+
                "         \"type\": \"keyword\" \n "+
                "       },\n "+
                "      \"name\":{\n "+
                "         \"type\": \"text\",\n "+
                "         \"analyzer\": \"ik_max_word\",\n "+
                "         \"copy_to\": \"{all}\"\n "+
                "      },\n "+
                "     \"address\":{\n "+
                "        \"type\": \"keyword\",\n "+
                "        \"index\": false \n "+
                "     }, \n "+
                "     \"price\":{ \n "+
                "        \"type\": \"integer\"\n "+
                "     }, \n "+
                "     \"score\":{\n "+
                "        \"type\": \"integer\"\n "+
                "     },\n "+
                "     \"brand\":{\n "+
                "       \"type\":\"keyword\",\n "+
                "       \"copy_to\": \"{all}\"\n "+
                "     },\n "+
                "    \"city\":{\n "+
                "       \"type\":\"keyword\"\n "+
                "     },\n "+
                "    \"starName\":{\n "+
                "       \"type\": \"keyword\"\n "+
                "     },\n "+
                "    \"business\":{\n "+
                "      \"type\":\"keyword\",\n "+
                "      \"copy_to\": \"{all}\"\n "+
                "    },\n "+
                "   \"latitude\":{\n "+
                "      \"type\": \"geo_point\"\n "+
                "    },\n "+
                "  \"location\":{\n "+
                "      \"type\": \"geo_point\"\n "+
                "    },\n "+
                "  \"pic\":{\n "+
                "      \"type\":\"keyword\",\n "+
                "      \"index\": false \n "+
                "   },\n "+
                "  \"all\":{\n "+
                "      \"type\": \"text\",\n "+
                "      \"analyzer\": \"ik_max_word\"\n "+
                "   }\n "+
                "   }\n "+
                "   }\n "+
                "   }  ";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在测试类中进行测试

    @SpringBootTest
    class HotelDemoApplicationTests {
    
        private RestHighLevelClient client;
    
        @Test
        void testCreateHotelIndex() throws IOException {
            // 1、 创建Request对象—————>索引库
            CreateIndexRequest request = new CreateIndexRequest("hotel");
            // 2、 请求参数,MAPPING_TEMPLATE是静态常量,内容是创建索引库的DSL语句(JSON文档)
            request.source(MAPPING_TEMPLATE, XContentType.JSON);
            // 3、发送请求    indices()————>返回的对象中包含索引库操作的所有方法
            client.indices().create(request, RequestOptions.DEFAULT);
        }
    
        //       初始化RestHighLevelClient
        @BeforeEach
        void setUp() {
            this.client=new RestHighLevelClient(RestClient.builder(
              HttpHost.create("http://192.168.197.140:9200")));      //  若是集群,可指定多个
        }
        @AfterEach
        //  销毁
        void tearDown() throws IOException {
            this.client.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    启动测试类,进入浏览器查询索引库已创建成功!!!
    在这里插入图片描述

    5、利用JavaRestClient删除索引库

    @Test
        void testDeleteHotelIndex() throws IOException {
            // 1、 创建Request对象
            DeleteIndexRequest request = new DeleteIndexRequest("hotel");
            // 2、 发起请求
            client.indices().delete(request, RequestOptions.DEFAULT);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6、利用JavaRestClient判断索引库是否存在

        @Test
        void testExistsHotelIndex() throws IOException {
            // 1、 创建Request对象
            GetIndexRequest  request=new GetIndexRequest("hotel");
            // 2、 发起请求
            boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
            System.err.print(exists ? "索引库已存在!" : "索引库不存在!");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    索引库操作总结

    索引库操作的基本步骤:
    初始化RestHighLevelClient
    创建XxxIndexRequest。XXX是CreateGetDelete
    准备DSL( Create时需要)
    发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、RestClient操作文档

    案例:利用JavaRestClient实现文档的CRUD
    从数据库查询酒店数据,导入到hotel索引库,实现酒店数据的CRUD。
    1、初始化JavaRestClient

    2、利用JavaRestClient新增酒店数据
    先查询酒店数据,然后给这条数据创建倒排索引,便可完成添加

    @SpringBootTest
    public class ElasticSearchDocumentTest {
    
        @Autowired
        private IHotelService hotelService;
        private RestHighLevelClient client;
        
        // 新增文档
        @Test
        void testIndexDocument() throws IOException {
    
            Hotel hotel = hotelService.getById(61083L);
            //转换数据   (由数据库类型转化为索引库所需要的类型)
            HotelDoc hoteldoc=new HotelDoc(hotel);
    
         // 1、 创建Request对象 (需转成字符串,索引库对于id的要求都为keyword类型,因此都为字符串)
            IndexRequest request=new IndexRequest("hotel").id(hotel.getId().toString());
            // 2、 准备JSON文档
            request.source(JSON.toJSONString(hoteldoc), XContentType.JSON);
            // 3、 发送请求——————index: 创建倒排索引
            client.index(request, RequestOptions.DEFAULT);
        }
    
        //  初始化RestHighLevelClient
        @BeforeEach
        void setUp() {
            this.client=new RestHighLevelClient(RestClient.builder(
             HttpHost.create("http://192.168.197.140:9200")    //  若是集群,可指定多个
           //HttpHost.create("http://192.168.197.141:9200"),
           //HttpHost.create("http://192.168.197.141:9200")
            ));
        }
        @AfterEach
            //  销毁
        void tearDown() throws IOException {
            this.client.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    新增文档成功!!!
    在这里插入图片描述

    3、利用JavaRestClient根据id查询酒店数据(根据id查询到的文档数据是json,需要反序列化为java对象

    // 查询文档
        @Test
        void  testGetDocumentByID() throws IOException {
            //  1、创建Request对象
            GetRequest request = new GetRequest("hotel", "61083");
            //  2、发送请求,得到结果
            GetResponse response=client.get(request,RequestOptions.DEFAULT);
            //  3、解析响应结果
            String json = response.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);   //利用fastjson反序列化
            System.err.println(hotelDoc);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查询文档成功!!!
    在这里插入图片描述

    4、利用JavaRestClient删除酒店数据

          // 删除文档
          @Test
            void testSelectDocumentById() throws IOException {
            // 1、获取request对象
                DeleteRequest request=new DeleteRequest("hotel","61083");
            // 2、删除文档             
                client.delete(request,RequestOptions.DEFAULT);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5、利用JavaRestClient修改酒店数据

    方式一:全量更新。再次写入id一样的文档,就会删除旧文档,添加新文档
    方式二:局部更新。只更新部分字段,此处为方式二
    
    • 1
    • 2
      // 更新文档
        @Test
        void testUpdateDocumentById() throws IOException {
            // 1、获取request对象
            UpdateRequest request = new UpdateRequest("hotel","61083");
            // 2、 准备参数,每两个参数为一对   key value
            request.doc(
                    "age",18,
                    "name","GY"
            );
            // 3、更新文档
            client.update(request,RequestOptions.DEFAULT);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    文档操作总结

    文档操作的基本步骤:
    初始化RestHighLevelClient
    创建XxxRequest。XXX是IndexGetUpdateDelete
    准备参数(IndexUpdate时需要)
    发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete
    解析结果(Get时需要)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    四、RestClient操作文档——批量导入功能

    案例:利用JavaRestClient批量导入酒店数据到ES(批量查询酒店数据,然后批量导入索引库中)

    1、利用mybatis-plus查询酒店数据
    2、将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)
    3、利用JavaRestClient中的Bulk批处理,实现批量新增文档,示例代码如下

        // 五、批量导入文档
        @Test
         void  testBulkRequest() throws IOException {
            // 批量查询数据
             List<Hotel> hotels = hotelService.list();
    
             // 1、创建request对象
             BulkRequest request = new BulkRequest();
             // 2、创建新增文档的Request对象
                   // 将数据转换为文档类型
             for (Hotel hotel : hotels) {
                 HotelDoc hotelDoc = new HotelDoc(hotel);
                 request.add(new IndexRequest("hotel")
                         .id(hotelDoc.getId().toString())
                         .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
             }
            // 3、发送请求
            client.bulk(request,RequestOptions.DEFAULT);
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    批量查询:
    GET /hotel/_search
    
    • 1
    • 2
  • 相关阅读:
    Python实现飞翔的小鸟
    LeetCode220726_50、填充每个节点的下一个右侧节点指针
    SpringCloud无介绍快使用,sentinel服务熔断功能(二十四)
    MySQL主从数据库(主读从写)
    力扣113题引发的关于DFS和回溯的一点思考
    Springboot结合Redis实现分布式定时任务
    CC导入UE5 人物眼球变白,睫毛粗解决办法思路提供
    什么是胆囊结石?
    微服务架构中注册中心Zookeeper和Eureka我们应该怎么选?
    多位数按键操作(不闪烁)数码管显示
  • 原文地址:https://blog.csdn.net/m0_56188609/article/details/127624569