当前位置:   article > 正文

SpringCloud——分布式搜索elasticsearch之RestClient

SpringCloud——分布式搜索elasticsearch之RestClient

前言:
Elasticsearch是一个开源的分布式搜索和分析引擎,它提供了一个基于HTTP协议的RESTful API,用于与Elasticsearch集群进行交互。
本文主要介绍了Elasticsearch Java High-Level REST Client 来操作 Elasticsearch。该客户端封装了底层的 RESTful API,并提供了更简单和方便的接口,以进行索引、搜索、聚合等操作。


1、RestClient操作索引库

1、定义mapping属性

简介:RestClient是Elasticsearch Java客户端库的一部分,它提供了一种低级别的方式来与Elasticsearch集群进行通信。它是一个轻量级的HTTP客户端,用于发送请求和接收响应。

通过RestClient,我们可以直接发送HTTP请求(如GET、POST、PUT、DELETE等)到Elasticsearch集群的RESTful API端点,并处理响应数据。它提供了一些方便的方法和功能,用于执行索引、搜索、聚合、更新、删除等操作。
官方文档:

链接: https://www.elastic.co/guide/en/elasticsearch/client/index.html
在这里插入图片描述
通过案例形式讲解JavaRestClient创建、删除索引库,判断索引库是否存在
需要的文件:链接: https://pan.baidu.com/s/1kiFjO_Vqyl6-xJcDXrY8Xg?pwd=x1e7
提取码:x1e7

tb_hotel.sql分析:
将sql文件导入到数据库:

在这里插入图片描述根据数据库表设计定义mapping属性:
在这里插入图片描述定义mapping时候我们要考虑的问题:

字段名、数据类型、是否参与搜索、是否分词、分词器是什么?

这段代码是用于创建名为"hotel"的索引,并定义了该索引的映射(mapping)。在Elasticsearch中,索引是用于组织和存储文档的地方,而映射定义了文档中的字段及其属性。

PUT /hotel
{
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "keyword",
          "index" : false
        },
        "all" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "brand" : {
          "type" : "keyword",
          "copy_to" : [
            "all"
          ]
        },
        "business" : {
          "type" : "keyword",
          "copy_to" : [
            "all"
          ]
        },
        "city" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "location" : {
          "type" : "geo_point"
        },
        "name" : {
          "type" : "text",
          "copy_to" : [
            "all"
          ],
          "analyzer" : "ik_max_word"
        },
        "pic" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "integer"
        },
        "score" : {
          "type" : "integer"
        },
        "starName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "startName" : {
          "type" : "keyword"
        }
      }
    }
}
  • 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
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

现在对其中其中内容进行解释

“PUT /hotel”: 这是一个PUT请求,用于创建或更新名为"hotel"的索引。通过发送此请求到Elasticsearch的特定端点,可以执行相应的操作。

“mappings”: 这是一个映射定义的部分,用于指定索引中文档的字段和属性。

“properties”: 它是映射的根节点,表示文档的属性集合。

“address”: 定义了一个名为"address"的字段,其类型为"keyword",并设置了"index"为false。这表示"address"字段的内容将不会进行分词,以精确匹配方式进行索引。

“all”: 定义了一个名为"all"的字段,其类型为"text",并使用"ik_max_word"分析器。该字段用于全文搜索,将"brand"、"business"和"name"字段的内容复制到"all"字段中,以便进行全文检索。

“brand”, “business”, “city”, “id”, “location”, “name”, “pic”, “price”, “score”, “starName”, “startName”: 这些是其他字段的定义,指定了它们的类型、属性和分析器(如果适用)。

“location”: 定义了一个名为"location"的字段,其类型为"geo_point",用于存储地理位置数据。

“fields”: 在"starName"字段中,使用了一个额外的子属性"fields",其中定义了一个名为"keyword"的字段。这是为了支持同时进行全文搜索和精确匹配,其中"starName.keyword"字段将被用于精确匹配。

2、创建项目,初始化JavaRestClient

创建Sprinboot项目:

springboot版本:2.7.12、es版本:7.12.1、mysql版本:8.0.31

导入项目,这里我们以黑马旅游demo项目为例:
链接: https://pan.baidu.com/s/17mPIg3NKkNjhJcL0-4-jUg?pwd=h0b8
提取码:h0b8

引入依赖文件

声明Elasticsearch REST High-Level Client库的依赖,该库是用于Elasticsearch的Java客户端库。

<!--es-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

spring boot默认的版本是7.6.2我们需要覆盖版本,

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

初始化操作:

我们在项目中添加单元测试,将RestClient初始化操作:

public class HotelIndexTest {
    private RestHighLevelClient client;

    /**
    * @Description: setUp 初始化客户端
    * @Param: * @param
    * @return: void
    * @Author: 508816739@qq.com
    * @Date: 17:25 2023/4/9
    */
    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.75.135:9200")
//                HttpHost.create("http://192.168.75.133:5601"), #可指定多个
//                HttpHost.create("http://192.168.75.133:5601")
        ));
    }

    //销毁客户端
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();

    }

    @Test
    void testInit() {
        System.out.println(client);
    }
}
  • 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

初始化成功:在这里插入图片描述

2、创建索引库

之前我们在Kibana中创建使用的PUT命令,现在我们直接使用java的api创建索引库
在这里插入图片描述我们还是使用以下代码创建:

{
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "keyword",
          "index" : false
        },
        "all" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "brand" : {
          "type" : "keyword",
          "copy_to" : [
            "all"
          ]
        },
        "business" : {
          "type" : "keyword",
          "copy_to" : [
            "all"
          ]
        },
        "city" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "location" : {
          "type" : "geo_point"
        },
        "name" : {
          "type" : "text",
          "copy_to" : [
            "all"
          ],
          "analyzer" : "ik_max_word"
        },
        "pic" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "integer"
        },
        "score" : {
          "type" : "integer"
        },
        "starName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "startName" : {
          "type" : "keyword"
        }
      }
    }
}
  • 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
  • 60
  • 61
  • 62
  • 63
  • 64

首先我们需要创建一个常量用于保存DSL语句
新建包:constants、新建类HotelContants

public class HotelConstants {
    public static final String MappingTemplate = "{\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" +
            "      \"startName\": {\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

在单元测试类中加入代码:这段代码用于创建索引库的操作

@Test
void createHotelIndex() throws IOException {
    //1.创建request对象
    CreateIndexRequest request = new CreateIndexRequest("hotel");
    //2.准备请求的参数(执行的json语句,指定类型是json类型)
    request.source(HotelConstants.MappingTemplate, XContentType.JSON);
    //3.发送请求
    client.indices().create(request, RequestOptions.DEFAULT);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

创建成功:
在这里插入图片描述在Kibana中查看我们创建的索引库
在这里插入图片描述

3、删除索引库、判断索引库是否存在

/**
* @Description: testDeleteHotelIndex 删除索引库对象
* @Param: * @param
* @return: void
* @Author: 508816739@qq.com
* @Date: 21:24 2023/4/10
*/
@Test
void testDeleteHotelIndex() throws IOException {
    //1.创建request对象
    DeleteIndexRequest request = new DeleteIndexRequest("hotel");
    //3.发送请求
    client.indices().delete(request, RequestOptions.DEFAULT);
}


/**
* @Description: testExistsHotelIndex 判断索引库是否存在
* @Param: * @param
* @return: void
* @Author: 508816739@qq.com
* @Date: 21:25 2023/4/10
*/
@Test
void testExistsHotelIndex() throws IOException {
    //1.创建request对象
    GetIndexRequest request = new GetIndexRequest("hotel");
    //3.发送请求
    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
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

连续运行代码后:
在这里插入图片描述索引库已经被删除

2、RestHighLevelClient操作文档

1、RestClient——新增文档

建立单元测试类,然后我们直接进行初始化客户端操作,然后再进行新增文档操作

    private RestHighLevelClient client;

    @Autowired
    private IHotelService hotelService;

    /**
    * @Description: setUp 初始化客户端
    * @Param: * @param
    * @return: void
    * @Author: 508816739@qq.com
    * @Date: 17:25 2023/4/9
    */
    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.75.135:9200")
//                HttpHost.create("http://192.168.75.133:5601"), #可指定多个
//                HttpHost.create("http://192.168.75.133:5601")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();

    }

   @Test
   void testAddDocument() throws IOException {
        //根据id查询数据
       Hotel hotel = hotelService.getById(61083L);
       HotelDoc hotelDoc = new HotelDoc(hotel);

       //1.准备Resquest对象
       IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
       //2.准备Json文档,先将hotelDoc对象序列化为Json类型
       request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
       //3.发送请求
       client.index(request, RequestOptions.DEFAULT);
   }
  • 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

在这里插入图片描述

在上述代码中我们先从数据库中拿到一个Hotel对象,将其id设置为HotelDoc类型,再将其转换为json类型,最终存入es的索引库"hotel"中

2、RestClient——查询文档

获取指定索引库的文档数据:

   @Test
   void testGetDocumentById() throws IOException {
        //1.准备Request 获取指定数据请求名称是GetRequest参数是: 索引库名,文档id
       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);
       System.out.println(hotelDoc);
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述上述代码我们通过GetRequest获取指定索引库的指定文档,通过文档id获取指定文档。

3、RestClient——更新文档

  @Test
   void testUpdateDocumentById() throws IOException {
        //1.创建request对象这是更新文档的对象
       UpdateRequest request = new UpdateRequest("hotel","61083");
       //2.准备参数
       request.doc(
               "price","952",
               "starName","四钻"
       );
       //3.执行更新文档操作
       client.update(request,RequestOptions.DEFAULT);
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述通过UpdateRequest 更新文档信息。

4、RestClient——删除文档

   @Test
   void testDeleteDocumentById() throws IOException {

       //1.创建删除文档更新请求
       DeleteRequest request = new DeleteRequest("hotel", "61083");
       //2.执行删除操作
       DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
       System.out.println(delete);
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

通过DeleteRequest 删除指定索引库的指定文档id的文档。
在这里插入图片描述

5、RestClient——批量导入文档

   @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对象
           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

上述代码我们批量插入数据,先通过hotelService获取数据然后将其转换为HotelDoc对象,最后进行插入操作。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/659140
推荐阅读
相关标签
  

闽ICP备14008679号