【ElasticSearch】JavaRestClient实现索引库和文档的增删改查

文章目录

  • 一、RestClient
    • 1、什么是RestClient
    • 2、导入demo工程
    • 3、数据结构分析与索引库创建
    • 4、初始化JavaRestClient
  • 二、RestClient操作索引库
    • 1、创建索引库
    • 2、删除索引库
    • 3、判断索引库是否存在
  • 三、RestClient操作文档
    • 1、新增文档
    • 2、查询文档
    • 3、修改文档
    • 4、删除文档
    • 5、批量导入文档

一、RestClient

1、什么是RestClient

ES官方提供了各种不同语言的客户端,用来操作ES,即RestClient。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。

官方文档地址:
https://www.elastic.co/guide/en/elasticsearch/client/index.html

在这里插入图片描述
在这里插入图片描述

2、导入demo工程

数据库信息如下:

mysql -h localhost -P3306 -uroot -padmian123 testDB < tb_hotel.sql

在这里插入图片描述

导入demo工程,基本结构如下:

在这里插入图片描述

3、数据结构分析与索引库创建

ES的mapping要考虑的点主要有:

  • 字段名(name)
  • 字段类型(type)
  • 是否参与搜索(index)
  • 是否分词(type/keyword)
  • 分词时,分词器用哪种(analyzer)

接下来,照着表结构,创建ES索引库:

在这里插入图片描述

PUT /hotel
{"mappings": {"properties":{"id":{"type": "keyword"  //注意这个类型},"name":{"type": "text","analyzer": "ik_max_word","copy_to": "all"},"address":{"type": "keyword", "index": false   //根据业务场景,用户刚来,不会去搜地址address,不参与搜索,index改为false,不再默认,类型选用keyword},"price":{"type": "integer"},"score":{   //price、score等将来要参与过滤和排序,需要index,用默认的true"type": "integer"},"brand":{  //city、brand品牌参与搜索,且不分词"type":"keyword","copy_to": "all"},"city":{"type":"keyword"},"starName":{  //不用下划线"type":"keyword"},"business":{"type": "keyword","copy_to": "all"},"location":{"type":"geo_point"   //经纬度两个字段合并为location,用ES的特定类型geo_point},"pic":{"type": "keyword","index": false  //pic既不分词,也不搜索},"all":{  //copy_to用的"type":"text","analyzer": "ik_max_word"}}}
}

用户就输入一个虹桥,我既想返回地址带虹桥的,也想返回商圈在虹桥的,还想返回酒店名称带虹桥的,如何实现?

加all字段,给需要的字段里加上从copy_to,这样all字段就可以代表这些加了copy_to的字段。实现了在一个字段里搜到多个字段的内容。

在这里插入图片描述
在这里插入图片描述

4、初始化JavaRestClient

  • 引入es的RestHighLevelClient依赖
<dependency>   <groupId>org.elasticsearch.client</groupId>    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
  • 因为SpringBoot下默认的ES版本是7.6.2,所以我们需要定义properties覆盖默认的ES版本
<properties>    <java.version>1.8</java.version>    <elasticsearch.version>7.12.1</elasticsearch.version> 
</properties>
  • 初始化RestHighLevelClient
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(       HttpHost.create("http://10.4.130.110:9200"),HttpHost.create("http://10.4.130.111:9200"),HttpHost.create("http://10.4.130.112:9200")  //集群模式写多个
));

在单元测试里看下效果,打印restHighLevelClient对象:
在这里插入图片描述
在这里插入图片描述

二、RestClient操作索引库

1、创建索引库

示例代码:

@Test
void testCreateHotelIndex() throws IOException {    // 1.创建Request对象    CreateIndexRequest request = new CreateIndexRequest("hotel");    // 2.请求参数,MAPPING_TEMPLATE是静态常量字符串,内容是创建索引库的DSL语句    request.source(MAPPING_TEMPLATE, XContentType.JSON);    // 3.发起请求    client.indices().create(request, RequestOptions.DEFAULT);
}

在这里插入图片描述
将创建索引库的DSL语句以静态字符串常量的形式统一写在常量类里:

在这里插入图片描述
运行完成后,查看ES索引库:

GET /hotel

在这里插入图片描述

整个过程,和我们去Kiana手动执行DSL对比:

在这里插入图片描述

2、删除索引库

示例代码:

@Test
void testDeleteHotelIndex() throws IOException {  // 1.创建Request对象     DeleteIndexRequest request = new DeleteIndexRequest("hotel");    // 2.发起请求    client.indices().delete(request, RequestOptions.DEFAULT);
}

3、判断索引库是否存在

示例代码:

@Test
void testExistsHotelIndex() throws IOException {// 1.创建Request对象    GetIndexRequest request = new GetIndexRequest("hotel");    // 2.发起请求     boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);    // 3.输出    System.out.println(exists);
}

在这里插入图片描述

小结:

在这里插入图片描述

三、RestClient操作文档

接下来利用JavaRestClient实现文档的CRUD,去数据库查询酒店数据,导入到hotel索引库,实现酒店数据的CRUD。

和操作索引库一样,还是要先完成JavaRestClient的初始化:

public class ElasticsearchDocumentTest {   // 客户端   private RestHighLevelClient client; @BeforeEach    void setUp() {        client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")));    }  @AfterEach    void tearDown() throws IOException {        client.close();    }
}

接下来要在mysql查数据,写下Service层接口,让它继承MyBatisPlus的IService<PO>

import com.baomidou.mybatisplus.extension.service.IService;public interface IHotelService extends IService<Hotel> {
}

1、新增文档

先看下DSL语法和使用JavaRestClient操作代码来实现的对比:

在这里插入图片描述

以上是简单逻辑和流程。注意MySQL中查出来的实体类字段和DSL下面的json字段不一样,这是tb_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,将Hotel类封装成为和ES索引库字段对应的类

@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();  //对于这些不用包装的字段,直接get到后赋值给包装对象的属性就行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();}
}

接下来实现去数据库查询酒店数据,导入到hotel索引库:

@Resource
IHotelService iHotelService;@Test
void testIndexDocument() throws IOException {//从MySQL查Hotel hotel = iHotelService.getById(60359L);   //封装HotelDoc hotelDoc = new HotelDoc(hotel);//创建requestIndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());//放入要新增的json传request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);//发请求client.index(request, RequestOptions.DEFAULT);}

2、查询文档

根据id查询到的文档数据是json,再反序列化成Java对象。代码和DSL语句的对比:

在这里插入图片描述

@Test
void testGetDocumentById() throws IOException {GetRequest request = new GetRequest("hotel","60359");GetResponse response = client.get(request,RequestOptions.DEFAULT);//看上图DSL执行返回结果中有个_source,这个getSource方法就是拿这个数据String json = response.getSourceAsString();//解析HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);System.out.println(hotelDoc);
}

在这里插入图片描述

3、修改文档

接下来根据id去修改ES文档的酒店数据。修改文档数据有两种方式:

方式一:全量更新。再次写入id一样的文档,就会删除旧文档,添加新文档
方式二:局部更新。只更新部分字段

实现下方式二:
在这里插入图片描述

@Test
void testUpdateDocumentById() throws IOException {UpdateRequest request = new UpdateRequest("hotel","60359");request.doc("price","0.01","startName","四星级");client.update(request,RequestOptions.DEFAULT);
}

4、删除文档

根据id删除文档数据:

在这里插入图片描述

@Test
void testDeleteDocumentById() throws IOException {DeleteRequest request = new DeleteRequest("hotel","60359");client.delete(request,RequestOptions.DEFAULT);
}

再get已经无数据:

在这里插入图片描述


小结:
在这里插入图片描述

5、批量导入文档

接下来批量查询酒店数据,然后批量导入索引库中,实现思路:

  • 利用mybatis-plus查询酒店数据
  • 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)
  • 利用JavaRestClient中的Bulk批处理,实现批量新增文档

代码逻辑:

在这里插入图片描述

@Test
void testBulk() throws IOException {//从MySQL查到所有数据List<Hotel> hotels = iHotelService.list();BulkRequest request = new BulkRequest();//遍历Hotel的对象集合for(Hotel hotel : hotels){//Hotel转HotelDocHotelDoc 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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14107.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SWPUCTF 2022 新生赛]js_sign

[SWPUCTF 2022 新生赛]js_sign 查看源码js文件 hint的意思是敲击码 解出flag&#xff0c;记得去掉nssctf&#xff0c;包上NSSCTF{} Tap Code - 许愿星 (wishingstarmoye.com)

Linux(Ubuntu)+Qt+C++与OpenCV窗体程序使用

程序示例精选 Linux(Ubuntu)QtC与OpenCV窗体程序使用 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<Linux(Ubuntu)QtC与OpenCV窗体程序使用>>编写代码&#xff0c;代码整洁&am…

基于Python爬虫+KNN数字验证码识别系统——机器学习算法应用(含全部工程源码)+训练数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境 模块实现1. 数据爬取2. 去噪与分割3. 模型训练及保存4. 准确率验证 系统测试工程源代码下载其它资料下载 前言 本项目利用Python爬虫技术&#xff0c;通过网络爬取验证码图片&#xff0c;并通过一系列的处理步…

javassist implements interface 模拟mybatis 生成代理类

动态创建代理对象的工具类 package com.wsd.util;import org.apache.ibatis.javassist.ClassPool; import org.apache.ibatis.javassist.CtClass; import org.apache.ibatis.javassist.CtMethod; import org.apache.ibatis.session.SqlSession;import java.lang.reflect.Const…

【C++ OJ练习】4.字符串中的第一个唯一字符

1.题目链接 力扣 2.解题思路 利用计数排序的思想 映射进行计数 最后计数为1的那个字符就是唯一字符 从前往后遍历 可以得到 第一个唯一字符 3.代码 class Solution { public:int firstUniqChar(string s) {//使用映射的方式统计次数 计数排序思想int count[26] { 0 };fo…

rpm包安装mysql8.0

一、环境准备 1查看本机IP地址&#xff0c;使用Xshell工具登录 [rootmysql ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope ho…

基于java+swing+mysql商城购物系统

基于javaswingmysql商城购物系统 一、系统介绍二、功能展示1.项目骨架2.主界面3.用户登陆4.添加商品类别5、添加商品6、商品管理 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java SE项目 项目名称&#xff1a;商城购物系统 用户类型&#xff1a;双…

SpringMVC跨域写入Cookie

前后端分离的项目&#xff0c;SpringMVCTomcat(SpringBoot)&#xff0c;前端Vueaxios。 不建议后端去写入Cookie&#xff0c;一般都是在前端写入Cookie&#xff0c;如果后端使用&#xff1a;CrossOrigin(origins "http://localhost", allowCredentials "true…

SpringBoot实战(二十)集成Druid连接池

目录 一、简介1.定义2.特点3.竞品对比 二、搭建测试项目1.Maven依赖2.yaml配置2.1 JDBC配置2.2 连接池配置2.3 监控配置 三、测试1.查看监控页面2.单元测试 四、补充&#xff1a;1.如何打印慢SQL&#xff1f;2.去除广告3.如何手动获取监控内容 一、简介 1.定义 Druid数据库连…

EtherCAT转TCP/IP网关ethercat最大通讯距离

天啊&#xff01;你们听说了吗&#xff1f;数据互联互通问题终于迎来了突破性进展&#xff01;作为生产管理系统的关键部分&#xff0c;数据互联互通一直是个大问题。然而&#xff0c;ETHERCAT和TCP/IP是两个不同的协议&#xff0c;它们之间的通讯一直是个大 问题。但是&#x…

【论文基本功】【LaTeX】参考文献中常见属性的用法及特点(bib文件)【IEEE论文】

【论文基本功】【LaTeX】参考文献中常见属性的用法及特点&#xff08;bib文件&#xff09;【IEEE论文】 一、author&#xff08;作者&#xff09;1. 使用方法用法1&#xff1a;作者名字的两种写法用法2&#xff1a;使用and连接不同作者姓名用法3&#xff1a;超过3个作者时如何使…

使用Jetpack Compose集成WebView

在Android开发中&#xff0c;WebView是一个非常重要的组件&#xff0c;它可以用来显示网页或加载在线内容。然而&#xff0c;在Jetpack Compose&#xff08;Google推出的新的UI工具包&#xff09;中&#xff0c;目前没有内置的WebView Composable。但不必担心&#xff0c;你可以…