5.4 RestClient

一、RestClient操作索引库

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过HTTP发送给ES。官网地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

1.1 创建索引

​ 创建mapping需要考虑的问题:字段名、数据类型、是否参与搜索、是否分词、如果分词,分词器是什么

  1. 创建索引,需要注意的地方:

    1. id,主键,索引,因此需要选择keyword类型,而非long或integer

    2. 地理坐标比较特殊,在es中有两种数据类型

      1. geo_point:由纬度(latitude)和经度(longitude)确定的一个点

      2. geo_shape:由多个gen_point组成的复杂几何图形

    3. 如果多个地方同时可以搜索,但是多个字段的查询效率不高,那么可以使用copy_to属性将字段拷贝到制定字段,对制定字段分词即可,可以减少多个搜索字段降低效率问题

      // 这里的all是一个指代,随便什么名字,如果改变,copy_to的值也要变成对应的名字
      "all": {
          "type": "text",
          "analyzer": "ik_max_word"
      },
      "字段": {
          "type": "keyword",
          "copy_to": "all"
      }
  2. 使用RestClient创建索引库

    1. 初始化RestHighLevelClient依赖

      <dependency>
          <groupId>org.elasticsearch.client</groupId>
          <artifactId>elasticsearch-rest-high-level-client</artifactId>
          <version>7.14.2</version>
      </dependency>

      备注:版本与使用的es版本相同

    2. 注意,因为SpringBoot中默认定义了ElasticSearch版本,因此需要我们手动变更es在SpringBoot中的默认版本

      <properties>
      	<elasticsearch.version>7.14.2</elasticsearch.version>
      </properties>

      备注:在pom文件的properties标签中添加elasticsearch.version标签去覆盖原有的内容

    3. 进行client初始化操作

      // 这里进行测试类编写测试
      
      public class EsHotelDemoTest {
      
          private RestHighLevelClient client;
      
          // 提前初始化操作
          @BeforeEach
          void setUp() {
              this.client = new RestHighLevelClient(
                      RestClient.builder(
                              HttpHost.create("http://127.0.0.1:9200")
                              // 集群写法
      //                        HttpHost.create("http://127.0.0.1:9200"),
      //                        HttpHost.create("http://127.0.0.1:9200"),
      //                        HttpHost.create("http://127.0.0.1:9200")
                      )
              );
          }
      
          // 结束后自动销毁操作
          @AfterEach
          void tearDown() throws IOException {
              this.client.close();
          }
      
      }
    4. 开始创建索引库

      @Test
      public void createHotelIndex() throws IOException {
          // 创建Request对象
          CreateIndexRequest request = new CreateIndexRequest("hotel");
          // 准备请求的参数:DSL语句
          request.source(HOTEL_MAPPING_TEMPLATE, XContentType.JSON);
          // 发送请求
          client.indices().create(request, RequestOptions.DEFAULT);
      }
      
      
      // 定义静态DSL语法
      public class DSLConstants {
          
          public static final String HOTEL_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" +
                  "      \"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 删除索引库

/**
 * 删除索引库
 */
@Test
public void deleteHotelIndex() throws IOException {
    // 创建Request对象
    DeleteIndexRequest request = new DeleteIndexRequest("hotel");
    // 发送请求
    client.indices().delete(request, RequestOptions.DEFAULT);
}

1.3 判断索引库是否存在

/**
 * 判断索引库是否存在
 */
@Test
public void existsHotelIndex() throws IOException {
    // 创建Request对象
    GetIndexRequest request = new GetIndexRequest("hotel");
    // 发起请求
    boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

    System.out.println(exists);
}

二、RestClient操作文档

2.1 新增文档

  1. 初始化client操作

    同索引库的操作

  2. 开始新增文档

    /**
     * 新建文档操作
     */
    @Test
    public void addHotelDocument() throws IOException {
    
        // 根据id获取一条
        Hotel hotel = hotelService.getById(61083L);
        // 数据转换为文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);
    
        // 准备Request对象
        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        // 准备json文档
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        // 发送请求
        client.index(request, RequestOptions.DEFAULT);
    }

    备注:校验方式:kibana中运行DSL:GET /hotel/_doc/61083

2.2 查询文档

/**
 * 查询文档操作
 */
@Test
public void getHotelDocument() throws IOException {
    // 准备request
    GetRequest request = new GetRequest("hotel", "61083");
    // 发送请求,得到相应
    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    // 解析结果
    String json = response.getSourceAsString();

    HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);

    System.out.println(hotelDoc);
}

2.3 删除文档

/**
 * 删除文档操作
 */
@Test
public void deleteHotelDocument() throws IOException {
    // 准备request
    DeleteRequest request = new DeleteRequest("hotel", "61083");
    // 发送请求
    client.delete(request, RequestOptions.DEFAULT);
}

2.4 修改文档

  1. 全量更新

    再一次写入id相同的文件即可,同添加文档操作,会删除旧文档,添加新文档

  2. 局部更新

    只更新部分字段

    /**
     * 修改文档操作
     */
    @Test
    public void updateHotelDocument() throws IOException {
        // 准备request
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        // 准备请求参数
        request.doc(
                "price", "900",
                "starName", "四钻"
        );
        // 发送请求
        client.update(request, RequestOptions.DEFAULT);
    }

    备注:局部更新时,需要注意更新的内容并非使用json格式,而是字符串类型,以逗号拼接,两两一组,分别表示字段,值

2.5 批量导入文档

/**
 * 批量导入文档操作
 */
@Test
public void addAllHotelDocument() throws IOException {
    // 批量查询酒店数据
    List<Hotel> hotelList = hotelService.list();

    // 创建request
    BulkRequest request = new BulkRequest();
    // 转换为文档类型
    for (Hotel hotel : hotelList) {
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 准备参数,添加多个request
        request.add(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    }
    // 发送请求
    client.bulk(request, RequestOptions.DEFAULT);
}

备注:查询全部:GET /hotel/_search

最后更新于

这有帮助吗?