RestClient操作文档

news/2025/2/14 4:20:39/

RestClient操作文档

  • 5.RestClient操作文档
    • 5.1.新增文档
      • 5.1.1.索引库实体类
      • 5.1.2.语法说明
      • 5.1.3.完整代码
    • 5.2.查询文档
      • 5.2.1.语法说明
      • 5.2.2.完整代码
    • 5.3.删除文档
    • 5.4.修改文档
      • 5.4.1.语法说明
      • 5.4.2.完整代码
    • 5.5.批量导入文档
      • 5.5.1.语法说明
      • 5.5.2.完整代码
    • 5.6.小结


5.RestClient操作文档

为了与索引库操作分离,我们再次参加一个测试类,做两件事情:

  • 初始化RestHighLevelClient
  • 我们的酒店数据在数据库,需要利用IHotelService去查询,所以注入这个接口
package cn.itcast.hotel;import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.service.IHotelService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.util.List;@SpringBootTest
public class HotelDocumentTest {@Autowiredprivate IHotelService hotelService;private RestHighLevelClient client;@BeforeEachvoid setUp() {this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")));}@AfterEachvoid tearDown() throws IOException {this.client.close();}
}

5.1.新增文档

我们要将数据库的酒店数据查询出来,写入elasticsearch中。


5.1.1.索引库实体类

数据库查询后的结果是一个Hotel类型的对象。结构如下:

@Data
@TableName("tb_hotel")
public class Hotel {@TableId(type = IdType.INPUT)private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String longitude;private String latitude;private String pic;
}

与我们的索引库结构存在差异:

  • longitude和latitude需要合并为location

因此,我们需要定义一个新的类型,与索引库结构吻合:

package cn.itcast.hotel.pojo;import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
public class HotelDoc {private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String location;private String pic;public HotelDoc(Hotel hotel) {this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude() + ", " + hotel.getLongitude();this.pic = hotel.getPic();}
}

5.1.2.语法说明

新增文档的DSL语句如下:

POST /{索引库名}/_doc/1
{"name": "Jack","age": 21
}

对应的java代码如图:

可以看到与创建索引库类似,同样是三步走:

  • 1)创建Request对象
  • 2)准备请求参数,也就是DSL中的JSON文档
  • 3)发送请求

变化的地方在于,这里直接使用client.xxx()的API,不再需要client.indices()了。


5.1.3.完整代码

我们导入酒店数据,基本流程一致,但是需要考虑几点变化:

  • 酒店数据来自于数据库,我们需要先查询出来,得到hotel对象
  • hotel对象需要转为HotelDoc对象
  • HotelDoc需要序列化为json格式

因此,代码整体步骤如下:

  • 1)根据id查询酒店数据Hotel
  • 2)将Hotel封装为HotelDoc
  • 3)将HotelDoc序列化为JSON
  • 4)创建IndexRequest,指定索引库名和id
  • 5)准备请求参数,也就是JSON文档
  • 6)发送请求

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
void testAddDocument() throws IOException {// 1.根据id查询酒店数据Hotel hotel = hotelService.getById(61083L);// 2.转换为文档类型HotelDoc hotelDoc = new HotelDoc(hotel);// 3.将HotelDoc转jsonString json = JSON.toJSONString(hotelDoc);// 1.准备Request对象IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());// 2.准备Json文档request.source(json, XContentType.JSON);// 3.发送请求client.index(request, RequestOptions.DEFAULT);
}

5.2.查询文档


5.2.1.语法说明

查询的DSL语句如下:

GET /hotel/_doc/{id}

非常简单,因此代码大概分两步:

  • 准备Request对象
  • 发送请求

不过查询的目的是得到结果,解析为HotelDoc,因此难点是结果的解析。完整代码如下:

可以看到,结果是一个JSON,其中文档放在一个_source属性中,因此解析就是拿到_source,反序列化为Java对象即可。

与之前类似,也是三步走:

  • 1)准备Request对象。这次是查询,所以是GetRequest
  • 2)发送请求,得到结果。因为是查询,这里调用client.get()方法
  • 3)解析结果,就是对JSON做反序列化

5.2.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
void testGetDocumentById() throws IOException {// 1.准备RequestGetRequest request = new GetRequest("hotel", "61082");// 2.发送请求,得到响应GetResponse response = client.get(request, RequestOptions.DEFAULT);// 3.解析响应结果String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);
}

5.3.删除文档

删除的DSL为是这样的:

DELETE /hotel/_doc/{id}

与查询相比,仅仅是请求方式从DELETE变成GET,可以想象Java代码应该依然是三步走:

  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
  • 2)准备参数,无参
  • 3)发送请求。因为是删除,所以是client.delete()方法

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
void testDeleteDocument() throws IOException {// 1.准备RequestDeleteRequest request = new DeleteRequest("hotel", "61083");// 2.发送请求client.delete(request, RequestOptions.DEFAULT);
}

5.4.修改文档


5.4.1.语法说明

修改我们讲过两种方式:

  • 全量修改:本质是先根据id删除,再新增
  • 增量修改:修改文档中的指定字段值

在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:

  • 如果新增时,ID已经存在,则修改
  • 如果新增时,ID不存在,则新增

这里不再赘述,我们主要关注增量修改。

代码示例如图:

与之前类似,也是三步走:

  • 1)准备Request对象。这次是修改,所以是UpdateRequest
  • 2)准备参数。也就是JSON文档,里面包含要修改的字段
  • 3)更新文档。这里调用client.update()方法

5.4.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
void testUpdateDocument() throws IOException {// 1.准备RequestUpdateRequest request = new UpdateRequest("hotel", "61083");// 2.准备请求参数request.doc("price", "952","starName", "四钻");// 3.发送请求client.update(request, RequestOptions.DEFAULT);
}

5.5.批量导入文档

案例需求:利用BulkRequest批量将数据库数据导入到索引库中。

步骤如下:

  • 利用mybatis-plus查询酒店数据

  • 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)

  • 利用JavaRestClient中的BulkRequest批处理,实现批量新增文档


5.5.1.语法说明

批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。

其中提供了一个add方法,用来添加其他请求:

可以看到,能添加的请求包括:

  • IndexRequest,也就是新增
  • UpdateRequest,也就是修改
  • DeleteRequest,也就是删除

因此Bulk中添加了多个IndexRequest,就是批量新增功能了。示例:

其实还是三步走:

  • 1)创建Request对象。这里是BulkRequest
  • 2)准备参数。批处理的参数,就是其它Request对象,这里就是多个IndexRequest
  • 3)发起请求。这里是批处理,调用的方法为client.bulk()方法

我们在导入酒店数据时,将上述代码改造成for循环处理即可。


5.5.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
void testBulkRequest() throws IOException {// 批量查询酒店数据List<Hotel> hotels = hotelService.list();// 1.创建RequestBulkRequest request = new BulkRequest();// 2.准备参数,添加多个新增的Requestfor (Hotel hotel : hotels) {// 2.1.转换为文档类型HotelDocHotelDoc hotelDoc = new HotelDoc(hotel);// 2.2.创建新增文档的Request对象request.add(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc), XContentType.JSON));}// 3.发送请求client.bulk(request, RequestOptions.DEFAULT);
}

5.6.小结

文档操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
  • 准备参数(Index、Update、Bulk时需要)
  • 发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
  • 解析结果(Get时需要)

学习笔记 from 黑马程序员

By – Suki 2023/4/8


http://www.ppmy.cn/news/41445.html

相关文章

手撕/手写/自己实现 BN层/batch norm/BatchNormalization python torch pytorch

计算过程 在卷积神经网络中&#xff0c;BN 层输入的特征图维度是 &#xff08;N,C,H,W&#xff09;, 输出的特征图维度也是 &#xff08;N,C,H,W&#xff09; N 代表 batch size C 代表 通道数 H 代表 特征图的高 W 代表 特征图的宽 我们需要在通道维度上做 batch normalizat…

Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择

GigaGAN是Adobe和卡内基梅隆大学学者们提出的一种新的GAN架构&#xff0c;作者设计了一种新的GAN架构&#xff0c;推理速度、合成高分辨率、扩展性都极其有优势&#xff0c;其证明GAN仍然是文本生成图像的可行选择之一。 文章链接&#xff1a;https://arxiv.org/abs/2303.0551…

【AIGC未来的发展方向】面向人工智能的第一步,一文告诉你人工智能是什么以及未来的方向分析

人工智能的概念 当人们提到“人工智能&#xff08;AI&#xff09;”时&#xff0c;很多人会想到机器人和未来世界的科幻场景&#xff0c;但AI的应用远远不止于此。现在&#xff0c;AI已经广泛应用于各种行业和生活领域&#xff0c;为我们带来了无限可能。 AI是一个广泛的概念…

《程序员面试金典(第6版)》面试题 08.14. 布尔运算(动态规划,分治,递归,难度hard++)

题目描述 给定一个布尔表达式和一个期望的布尔结果 result&#xff0c;布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数&#xff0c;算出有几种可使该表达式得出 result 值的括号方法。 示例 1: 输入: s “1^0|0|1”, result 0 …

干货分享 - MatLab || 与LaTeX的混合使用指南

目录 1、前言 2、Latex基础 3、Latex尝鲜 4、Latex在MatLab中换行 5、Latex在MatLab中小花招 6、附录1&#xff1a;Tex对照表 7、附录2&#xff1a;常用Tex字符 1、前言 LaTeX语言作为应用最广泛的Tex格式&#xff0c;Tex这种语言具有简单排版和程序设计的功能。 利用…

I/O软件的层次结构及其概念

I/O软件在计算机的什么部位 I/O (Input/Output) 软件是运行在计算机操作系统中的一种软件&#xff0c;用于管理计算机与外部设备之间的输入和输出数据交换。这种软件通常与计算机的驱动程序和硬件设备交互&#xff0c;以实现输入和输出数据的传输和处理。 因为 I/O 软件是操作…

同程旅行面试_4/14

今天准备了一上午-下午4:30 进行了30min面试 问八股居多&#xff0c;主要考题如下&#xff1a; 1. 说一下 和 的区别&#xff08;先进行类型转换&#xff0c;再进行值转换&#xff1f;&#xff09; 2.说一下flex布局 3.一栏固定 另一栏随着宽度改变而改变 4.说一下移动端适…

12.Union 结构

文章目录十二、Union 结构十二、Union 结构 有时需要一种数据结构&#xff0c;不同的场合表示不同的数据类型。比如&#xff0c;如果只用一种数据结构表示水果的“量”&#xff0c;这种结构就需要有时是整数&#xff08;6个苹果&#xff09;&#xff0c;有时是浮点数&#xff…