• 【SpringCloud】微服务技术栈入门6 - RestClient深入


    RestClient


    定义索引

    引入对应 sql 后,需要添加 sql 对应的 es 索引

    下面是根据 sql 结构来构建的索引树,我们需要插入到 es 里面,在这里先不要在 devtools 中实现,下一节我们将会使用 restclient 来插入这个索引

    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"
          },
          "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

    copy_to 字段的作用是将当前字段附加到另外一个字段内,当搜索时就会联合被附加的字段一起搜索

    比如上面将 business、brand 和 name 均附加到了 all 字段上,而被附加的 all 并不会额外添加内容,只是被搜索时他们三个会同时被检索,提高效率,仅此而已


    安装与配置测试类

    pom 内添加 es 依赖项,这里先略去版本

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

    然后到 properties 标签内添加 es 的版本,注意这里的版号一定要和你使用的 es 版本严格相等!
    比如我这边用的是 es7.8.0,就必须是这个版本!

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

    新建一个测试类,使用注解 @BeforeEach@AfterEach 来实现 restclient 链接与关闭的两大事务

    @SpringBootTest
    public class HotelIndexTest {
        private RestHighLevelClient client;
    
        @BeforeEach
        void setup() {
            this.client = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://localhost:9200")
            ));
        }
    
        @AfterEach
        void destory() throws IOException {
            client.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    插入索引

    首先新建一个常量类,把插入索引的 json 保存到里面去

    这段文本就是上上一节定义的插入索引 json

    package cn.itcast.hotel.constant;
    
    public class HotelConst {
        public static final String HOTEL_INDEX = "{\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" +
                "      \"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

    紧接着在测试类中编写插入 index 的方法即可

    @Test
    void testCreateIndex() throws IOException {
        // 创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        // 设置索引的源数据
        request.source(HotelConst.HOTEL_INDEX, XContentType.JSON);
        // 使用客户端执行创建索引请求
        client.indices().create(request, RequestOptions.DEFAULT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    你可以使用以下两个测试方法来实现删除索引以及判断对应索引存在与否

    // 删除索引
    @Test
    void testDeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        client.indices().delete(request, RequestOptions.DEFAULT);
    }
    
    // 通过get索引,判断get请求的返回值来看索引是否已经创建
    @Test
    void testExistIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("hotel");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    索引的 CRUD

    创建索引

    首先引入 IHotelService 用来通过 id 查询 mysql 对应记录
    然后通过 JSON.toJSONString 把对应的实体类转换为 JSON 字符串的格式用来创建索引

    @SpringBootTest
    public class ElasticSearchCRUDTest {
      @Autowired
      private IHotelService hotelService;
      private RestHighLevelClient client;
    
      @Test
      void testIndexDoc() throws IOException {
        Hotel hotelServiceById = hotelService.getById(61083L);
        HotelDoc hotelDoc = new HotelDoc(hotelServiceById);
    
        IndexRequest request = new IndexRequest("hotel").id(hotelServiceById.getId().toString());
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        client.index(request, RequestOptions.DEFAULT);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    根据指定 id 获取索引存储 JSON,并将其转换为实体类后输出

    @Test
    void testGetDoc() throws IOException{
        GetRequest request= new GetRequest("hotel","61083");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String source = response.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
        System.out.println(hotelDoc);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    更新字段

    字段更新有两种方式

    • 全量更新:删掉旧的,新建一个新的插进去
    • 局部更新:在原来的基础上更新需要的内容

    下面展示了局部更新的方法

    @Test
    void testUpdateDoc() throws IOException {
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        request.doc(
                "price", "2103",
                "starName", "星钻"
        );
        client.update(request, RequestOptions.DEFAULT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    删除文档就更简单了,直接提供索引以及对应的 id 就好了

    @Test
    void testDeleteDoc() throws IOException{
        DeleteRequest request = new DeleteRequest("hotel", "61083");
        client.delete(request, RequestOptions.DEFAULT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    批量导入文档

    使用 bulk 请求来实现批量索引查询

    @Test
    void testBulkImport() throws IOException {
        BulkRequest request = new BulkRequest();
        request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
        request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
        request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
        client.bulk(request, RequestOptions.DEFAULT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询所有酒店后使用 bulk 将他们依次插入索引

    @Test
    void testBulkIndex() throws IOException {
        List<Hotel> list = hotelService.list();
    
        BulkRequest request = new BulkRequest();
        for (Hotel hotel : list) {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            request.add(
                    new IndexRequest("hotel")
                            .id(hotelDoc.getId().toString())
                            .source(JSON.toJSONString(hotelDoc), XContentType.JSON)
            );
        }
        client.bulk(request, RequestOptions.DEFAULT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    STM32人脸识别系统设计(程序代码+论文)
    Android (微信扫码登录) 获取微信二维码+扫码登录
    Python eval()和exec()函数
    【金融项目】尚融宝项目(十四)
    我的vs把opencv配置进去了,通过几个测试代码显示可以,但是运行的时候报错经过验证图片路径和地址附加依赖项没有配置错))
    资讯网站实时翻译软件
    自学 TypeScript 第三天 使用webpack打包 TS 代码
    【概率与统计】聊聊一些常见的概率分布
    一起来部署项目-采购一台云服务器
    【Python】9*9乘法口诀表(while、for两种循环)
  • 原文地址:https://blog.csdn.net/delete_you/article/details/133611814