零、本文綱要
- 一、認(rèn)識(shí)RestClient
- 二、使用RestClient
1、基礎(chǔ)準(zhǔn)備
2、RestClient操作索引庫(kù)
...
③ 編寫創(chuàng)建索引庫(kù)方法
④ 編寫刪除索引庫(kù)方法
⑤ 編寫判斷是否存在索引庫(kù)方法
3、RestClient操作文檔
① 添加文檔數(shù)據(jù)方法
② 獲取文檔數(shù)據(jù)方法
③ 更新文檔數(shù)據(jù)方法
④ 刪除文檔數(shù)方法
⑤ 批量操作方法
tips:Ctrl + F快速定位所需內(nèi)容閱讀吧。
一、認(rèn)識(shí)RestClient
Java REST Client (deprecated) | Elastic
Overview (rest-high-level 7.12.1 API) (elastic.co)
ES官方提供了各種不同語(yǔ)言的客戶端,用來(lái)操作ES。這些客戶端的本質(zhì)就是組裝DSL語(yǔ)句,通過(guò)http請(qǐng)求發(fā)送給ES。
RestClient是提供給Java的客戶端。
二、使用RestClient
1、基礎(chǔ)準(zhǔn)備
- ① 創(chuàng)建表格
創(chuàng)建數(shù)據(jù)表tb_hotel,如下:
DROP TABLE IF EXISTS `tb_hotel`;
CREATE TABLE `tb_hotel` (
`id` bigint(20) NOT NULL COMMENT '酒店id',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店名稱',
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店地址',
`price` int(10) NOT NULL COMMENT '酒店價(jià)格',
`score` int(2) NOT NULL COMMENT '酒店評(píng)分',
`brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店品牌',
`city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所在城市',
`star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店星級(jí),1星到5星,1鉆到5鉆',
`business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商圈',
`latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '緯度',
`longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '經(jīng)度',
`pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店圖片',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
插入數(shù)據(jù),如下:
INSERT INTO `tb_hotel` VALUES (36934, '7天連鎖酒店(上海寶山路地鐵站店)', '靜安交通路40號(hào)', 336, 37, '7天酒店', '上海', '二鉆', '四川北路商業(yè)區(qū)', '31.251433', '121.47522', 'https://m.tuniucdn.com/fb2/t1/G1/M00/3E/40/Cii9EVkyLrKIXo1vAAHgrxo_pUcAALcKQLD688AAeDH564_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38609, '速8酒店(上海赤峰路店)', '廣靈二路126號(hào)', 249, 35, '速8', '上海', '二鉆', '四川北路商業(yè)區(qū)', '31.282444', '121.479385', 'https://m.tuniucdn.com/fb2/t1/G2/M00/DF/96/Cii-TFkx0ImIQZeiAAITil0LM7cAALCYwKXHQ4AAhOi377_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38665, '速8酒店上海中山北路蘭田路店', '蘭田路38號(hào)', 226, 35, '速8', '上海', '二鉆', '長(zhǎng)風(fēng)公園地區(qū)', '31.244288', '121.422419', 'https://m.tuniucdn.com/fb2/t1/G2/M00/EF/86/Cii-Tlk2mV2IMZ-_AAEucgG3dx4AALaawEjiycAAS6K083_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38812, '7天連鎖酒店(上海漕溪路地鐵站店)', '徐匯龍華西路315弄58號(hào)', 298, 37, '7天酒店', '上海', '二鉆', '八萬(wàn)人體育場(chǎng)地區(qū)', '31.174377', '121.442875', 'https://m.tuniucdn.com/fb2/t1/G2/M00/E0/0E/Cii-TlkyIr2IEWNoAAHQYv7i5CkAALD-QP2iJwAAdB6245_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (39106, '7天連鎖酒店(上海莘莊地鐵站店)', '閔行莘莊鎮(zhèn)七莘路299號(hào)', 348, 41, '7天酒店', '上海', '二鉆', '莘莊工業(yè)區(qū)', '31.113812', '121.375869', 'https://m.tuniucdn.com/fb2/t1/G2/M00/D8/11/Cii-T1ku2zGIGR7uAAF1NYY9clwAAKxZAHO8HgAAXVN368_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (39141, '7天連鎖酒店(上海五角場(chǎng)復(fù)旦同濟(jì)大學(xué)店)', '楊浦國(guó)權(quán)路315號(hào)', 349, 38, '7天酒店', '上海', '二鉆', '江灣、五角場(chǎng)商業(yè)區(qū)', '31.290057', '121.508804', 'https://m.tuniucdn.com/fb2/t1/G2/M00/C7/E3/Cii-T1knFXCIJzNYAAFB8-uFNAEAAKYkQPcw1IAAUIL012_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (416121, '如家酒店(北京西客站北廣場(chǎng)店)', '蓮花池東路120-2號(hào)6層', 275, 43, '如家', '北京', '二鉆', '北京西站/麗澤商務(wù)區(qū)', '39.896449', '116.317382', 'https://m.tuniucdn.com/fb3/s1/2n9c/42DTRnKbiYoiGFVzrV9ZJUxNbvRo_w200_h200_c1_t0.jpg');
- ② 引入依賴
elasticsearch相關(guān)依賴,如下:
<!--elasticsearch-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>
因?yàn)镾pringBoot默認(rèn)的ES版本是7.6.2,所以我們需要覆蓋默認(rèn)的ES版本:
<properties>
<!--指定我們所需的版本,覆蓋springboot默認(rèn)配置-->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
其他依賴,如下:
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis_plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!--mysql_connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--FastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!--commons-lang3:工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
- ③ application.yml
Ⅰ 配置服務(wù)端口;
Ⅱ 配置數(shù)據(jù)源;
Ⅲ 配置日志;
Ⅳ 配置mybatis-plus。
server:
port: 8089
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
logging:
level:
cn.test: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
type-aliases-package: cn.test.hotel.pojo
- ④ 編寫實(shí)體類
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;
}
HotelDoc類
@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();
}
}
geo_point類型屬性映射的形式有多種,官方文檔見(jiàn)此:Geopoint field type
,常見(jiàn)的形式如下圖。此處我們采用第2種形式,做屬性映射"location": "41.12,-71.34",所以在類型轉(zhuǎn)換的時(shí)候手動(dòng)拼接了屬性值this.location = hotel.getLatitude() + ", " + hotel.getLongitude();。

- ⑤ 編寫mapper接口及service接口&實(shí)現(xiàn)類
public interface HotelMapper extends BaseMapper<Hotel> {
}
public interface IHotelService extends IService<Hotel> {
}
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
}
2、RestClient操作索引庫(kù)
- ① 創(chuàng)建索引庫(kù)
Ⅰ 編寫創(chuàng)建索引庫(kù)語(yǔ)句:這個(gè)步驟可以在自己Dev Tools控制臺(tái)內(nèi)完成,然后將字段復(fù)制到IDEA。
public class HotelConstant {
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" +
" \"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" +
"}";
}
- ② 編寫測(cè)試類
@BeforeEach內(nèi)完成client對(duì)象的初始化配置,@AfterEach內(nèi)完成操作后的資源釋放。
public class HotelIndexTest {
private RestHighLevelClient client;
@BeforeEach
void setUp(){
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.253.128:9200")
));
}
... ...
@AfterEach
void tearDown(){
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- ③ 編寫創(chuàng)建索引庫(kù)方法
@Test
void createHotelIndex(){
// 1. 創(chuàng)建Request對(duì)象
CreateIndexRequest request = new CreateIndexRequest("hotel");
// 2. 準(zhǔn)備請(qǐng)求參數(shù)DSL語(yǔ)句
request.source(HotelConstant.MAPPING_TEMPLATE, XContentType.JSON);
// 3. 發(fā)送請(qǐng)求
try {
client.indices().create(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}

- ④ 編寫刪除索引庫(kù)方法
@Test
void deleteHotelIndex(){
// 1. 創(chuàng)建Request對(duì)象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
// 2. 發(fā)送請(qǐng)求
try {
client.indices().delete(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
- ⑤ 編寫判斷是否存在索引庫(kù)方法
@Test
void existsHotelIndex(){
// 1. 創(chuàng)建Request對(duì)象
GetIndexRequest request = new GetIndexRequest("hotel");
// 2. 發(fā)送請(qǐng)求
try {
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.err.println(exists ? "hotel index exists!" : "hotel index not exist!");
} catch (IOException e) {
e.printStackTrace();
}
}
不難看出對(duì)索引庫(kù)的操作有一定的相似性:
Ⅰ XXXIndexRequest:Create、Delete、Get的請(qǐng)求request對(duì)象;
Ⅱ client.indices().XXX():create、delete、get方法。
3、RestClient操作文檔
添加@SpringBootTest注解,注入hotelService:
@Resource
private IHotelService hotelService;
- ① 添加文檔數(shù)據(jù)方法
@Test
void addDocument(){
// 1. 查詢數(shù)據(jù)庫(kù)
Hotel hotel = hotelService.getById(36934L);
// 2. 封裝成DOC對(duì)象
HotelDoc hotelDoc = new HotelDoc(hotel);
// 3. 獲取request對(duì)象
IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
// 4. 將數(shù)據(jù)放入request
request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
// 5. 存儲(chǔ)數(shù)據(jù)
try {
client.index(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
- ② 獲取文檔數(shù)據(jù)方法
@Test
void getDocumentById(){
// 1. 創(chuàng)建request對(duì)象
GetRequest request = new GetRequest("hotel", "36934");
try {
// 2. 發(fā)送請(qǐng)求,得到結(jié)果
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 3. 解析結(jié)果
String json = response.getSourceAsString();
System.out.println(json);
} catch (IOException e) {
e.printStackTrace();
}
}
- ③ 更新文檔數(shù)據(jù)方法
@Test
void updateDocumentById(){
// 1. 創(chuàng)建request對(duì)象
UpdateRequest request = new UpdateRequest("hotel", "36934");
// 2. 設(shè)置更新字段
request.doc(
"price", "346",
"starName", "三鉆"
);
// 3. 更新文檔
try {
client.update(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
- ④ 刪除文檔數(shù)方法
@Test
void deleteDocumentById(){
// 1. 創(chuàng)建request對(duì)象
DeleteRequest request = new DeleteRequest("hotel", "36934");
// 2. 刪除文檔
try {
client.delete(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
- ⑤ 批量操作方法
@Test
void bulkRequest(){
// 1. 獲取請(qǐng)求對(duì)象
BulkRequest request = new BulkRequest();
// 2. 準(zhǔn)備參數(shù),添加多個(gè)新增的Request
// 2.1 批量獲取數(shù)據(jù)庫(kù)的數(shù)據(jù)
List<Hotel> hotelList = hotelService.list();
for (int i = 0; i < hotelList.size(); i++) {
// 2.2 獲取hotel對(duì)象
Hotel hotel = hotelList.get(i);
// 2.3 轉(zhuǎn)換成hotelDoc對(duì)象
HotelDoc hotelDoc = new HotelDoc(hotel);
/*// 2.4 獲取request對(duì)象
IndexRequest indexRequest = new IndexRequest("hotel").id(hotel.getId().toString());
// 2.5 將數(shù)據(jù)放入request
indexRequest.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
// 2.6 將indexRequest對(duì)象加入request
request.add(indexRequest);*/
request.add(new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON));
}
// 3. 批量添加
try {
client.bulk(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
不難看出對(duì)索引文檔的操作也具有一定的相似性:
Ⅰ XXXRequest:Index、Get、Update、Delete、Bulk的請(qǐng)求request對(duì)象;
Ⅱ client.XXX()方法:index、get、update、delete、bulk方法。
三、結(jié)尾
以上即為RestClient基礎(chǔ)的全部?jī)?nèi)容,感謝閱讀。