Springboot3整合Elasticsearch8(elasticsearch-java)

1、Elasticsearch的JAVA客户端选择

Elasticsearch官方支持的客户端

客户端名称简介使用建议
Elasticsearch Java API Client(新客户端)官方推荐的新客户端,基于 JSON Mapping(如 ElasticsearchClient 类),从 Elasticsearch 7.15 开始推出。✅推荐用于 Spring Boot 3+,Elasticsearch 8+
RestHighLevelClient(已废弃)基于 REST 的高级客户端,是 ES 6 ~ 7 的主力客户端,ES 8 中已标记为 deprecated。❌不推荐新项目使用
Low Level REST Client底层客户端,只提供 HTTP 封装,不解析 JSON。

🔧适合自定义协议或处理特殊 JSON 请求场景

Spring官方对Elasticsearch的封装

客户端名称简介特点
Spring Data ElasticsearchSpring 官方对 Elasticsearch 的数据访问封装,支持 Repository 风格的接口编程。👍开发效率高、和 JPA 风格一致,但功能不如原生客户端全

easy-es(dromara团队),国人之光!

客户端名称简介特点
easy-es风格类似 MyBatis-Plus,一致的 API 和分页查询方式,Java 开发者易于理解。👍开发效率高、但是是对RestHighLevelClient的深层封装,容易受版本影响,小团队维护

总结:

RestHighLevelClient 是ES7中使用最多的客户端,但是在ES8中已经废弃。

easy-es  是基于RestHighLevelClient封装的,会比较重,代码风格类似 MyBatis-Plus,熟悉MP的同学容易上手,但是容易受RestHighLevelClient和Elasticsearch版本的限制,并且目前社区虽然活跃,但项目主要靠小团队维护,不如官方客户端那样稳定长期。

Elasticsearch Java API Client 是 Elasticsearch 7.15 开始推出最新的客户端,能使用Elasticsearch中所有功能,首选首选!!!!!!

Spring Data Elasticsearch 是Spring 官方对 Elasticsearch的封装,Springboot3中已经弃用了RestHighLevelClient,选择引用了Elasticsearch Java API Client,直接解决了依赖版本冲突的问题,Spring社区强大,所以...不用我说了吧....选我!!!!!

2、Spring Data Elasticsearch 官方文档

Elasticsearch Clients :: Spring Data Elasticsearch

3、Springboot3整合Spring Data Elasticsearch

tips:我使用的是Springboot3.3.4版本

3.1 maven引入

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

引入成功之后可以看到:

elasticsearch的新客户端elasticsearch-java也被引入了进来。

3.2 配置

yml配置文件

spring:application:name: cloud-elasticsearchelasticsearch:uris: http://127.0.0.1:9200 #  这里还要注意是https还是http协议
#    username: elastic #如果有账号密码就要配置账号密码,否则可以不配置
#    password: 123456server:port: 20000

4、【简单使用】Spring Data Elasticsearch

4.1 创建ES实体类

创建完实体类后,启动项目Spring会自动根据注解,来创建ES的索引(index)和映射(mapping)

@Data
@Document(indexName = "news")
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public class EsNews {@Idprivate String id;@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")private String title;//标题@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")private String content;//内容@Field(type = FieldType.Keyword)private String author;//作者@Field(type = FieldType.Keyword)private List<String> tags;//标签@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")@JsonProperty("publish_date")private Date publishDate;//发布时间@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")@JsonProperty("create_time")private Date createTime;//创建时间@Field(type = FieldType.Long)@JsonProperty("view_count")private Long viewCount;//阅读量}

注解解析:

@Document(indexName = "news")

该实体对应的索引名称为:news

@Id

ES的唯一标识

@Field

@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")

Field(字段名) , type = FieldType.Text(字段类型为TEXT) ,analyzer = "ik_max_word"(存入时的分词器为ik_max_word),searchAnalyzer = "ik_smart"(搜索时的分词器为ik_smart)

@JsonProperty("publish_date")

ES中JSON字段,迎来进行序列化映射

tips:实际开发中业务实体类和ES实体类最好是分开的,业务实体类主要用来做数据库操作,ES实体类只用来做ES检索

4.2 继承ElasticsearchRepository接口

public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {}

查看ElasticsearchRepository源码可以看到

ElasticsearchRepository也继承了PagingAndSortingRepository(分页和排序接口)、CrudRepository(常用基础crud接口)

当你的类接口继承了ElasticsearchRepository后,你输入find,你会看到Spring帮你生成的所有常用简单的查询语句。

大部分关键词用法:

关键词说明等价 Elasticsearch 查询类型
findBy查询开始(必须)-
And / Or条件连接符bool 查询
Is / Equals等于term
Between在两个值之间range
LessThan小于range
LessThanEqual小于等于range
GreaterThan大于range
GreaterThanEqual大于等于range
After大于(时间)range
Before小于(时间)range
IsNull字段为 nullmust_not exists
IsNotNull / NotNull字段非 nullexists
Like类似(不建议用,Elasticsearch 中更推荐 Containingmatch (部分分词匹配)
NotLike不类似bool + must_not
StartingWith以…开头(需要 keyword 类型字段,match 不支持)prefix / wildcard
EndingWith以…结尾(需 keyword 类型字段)wildcard
Containing / Contains包含(常用于全文检索)match
NotContaining不包含bool + must_not
In包含在列表中terms
NotIn不包含在列表中bool + must_not terms
True / False布尔值判断term
OrderBy排序sort

4.3 CRUD接口使用

使用SpringBoot单元测试

4.3.1 新增

文档单个新增(save): 

    @Test@DisplayName("新增单个文档")void saveDoc(){EsNews news = new EsNews();news.setId("1");//如果不设置ID,Spring则会帮你生成一个ES风格的随机IDnews.setTitle("电影《不能说的秘密》热映");news.setContent("内容:不能说的秘密............牛X..");news.setAuthor("周杰伦");news.setTags(Arrays.asList("电影", "国产"));news.setPublishDate(new Date());news.setCreateTime(new Date());news.setViewCount(100L);esNewsRepository.save(news);}

文档批量新增(saveAll):

    @Test@DisplayName("批量新增文档")void saveBatchDoc(){List<EsNews> newsList = new ArrayList<>();for (int i = 1; i <= 11; i++) {EsNews news = new EsNews();news.setId(String.valueOf(i));news.setTitle("电影《CPW的奇幻世界 " + i + "》");news.setContent("内容 " + i);news.setAuthor("作者" + i);news.setTags(Arrays.asList("电影", "奇幻"));news.setPublishDate(new Date());news.setCreateTime(new Date());news.setViewCount(100L + i);newsList.add(news);}esNewsRepository.saveAll(newsList);}

4.3.3 修改

!!!ElasticsearchRepository!!!的修改跟新增是同一个接口,如果你的对象携带ID,那么ES会先查询文档库里是有存在这么一个ID,如果存在的话则进行 先删除 然后 覆盖!!

    @Test@DisplayName("新增单个文档")void saveDoc(){EsNews news = new EsNews();news.setId("1");//ES会先找文档库里是否存在改ID,先删除再覆盖news.setTitle("电影《不能说的秘密》热映");news.setContent("内容:不能说的秘密........牛X..更新覆盖操作");news.setAuthor("周杰伦");news.setTags(Arrays.asList("电影", "国产"));news.setPublishDate(new Date());news.setCreateTime(new Date());news.setViewCount(100L);esNewsRepository.save(news);}

如果你想做到只修改文档中其中一条数据,比如只把作者周杰伦修改成CPW,那就需要用到第五节【高阶用法】Elasticsearch Java API Client

4.3.3 查询

需求:我要查询文档编号为999的文档

tips:简单的查询,比如根据ID查询文档,ElasticsearchRepository已经自己封装好了,不用另外写。(findById)

    @Test@DisplayName("根据ID查询文档")void searchByID(){Optional<EsNews> news = esNewsRepository.findById("999");System.out.println(news);}

需求:我要分页查询,标题包含【奇幻世界】,作者精准是【作者1】的文档

tips:这种复杂多条件的就需要我们自己写,如果是模糊查询的则用Containing

1、EsNewsRepository新增接口findByTitleContainingOrAuthor:

public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {Page<EsNews> findByTitleContainingOrAuthor(String Title, String Author,Pageable pageable);}

2、使用

    @Test@DisplayName("分页查询条件")void searchAll(){Pageable pageable = PageRequest.of(0, 10);Page<EsNews> pageList = esNewsRepository.findByTitleContainingOrAuthor("奇幻世界","作者1",pageable);for (EsNews news : pageList) {System.out.println(news);}}

根据4.2中的关键词,还有更多的用法例如过滤、排序

4.3.4 删除

删除就没什么好说的了,直接上代码!

    @Test@DisplayName("根据ID删除文档")void deleteDocById(){esNewsRepository.deleteById("1");System.out.println("ID为1的文档删除成功");}@Test@DisplayName("批量删除文档")void deleteBatchDoc(){esNewsRepository.deleteAll();System.out.println("文档批量删除成功");}@Test@DisplayName("根据ID批量删除文档")void deleteBatchDocByIds(){List<String> idList = Arrays.asList("1", "2");esNewsRepository.deleteAllById(idList);System.out.println("根据ID批量删除文档删除成功");}

5、【高阶用法】Elasticsearch Java API Client

一句话:Spring Data Elasticsearch不能实现的,再用Elasticsearch Java API Client例如只更新数据中的个别字段数据,高级查询(聚合查询),bulk函数等。。

Elasticsearch Java API Client对熟悉ES语句的同学非常友好,学会基本代码用法跟写语句一样丝滑。

不熟悉语句建议看一下ES入门教程:Elasticsearch8(ES)保姆级菜鸟入门教程-CSDN博客

建议看着文档配合服用~

5.1 ElasticsearchClient

    @Autowiredprivate ElasticsearchClient elasticsearchClient;

所有的ES8功能都在ElasticsearchClient中,先来看看有哪些方法:

可以看出CRUD的方法和参数,分别不同:

查询的语句用的是SearchRequest

更新的语句用的是UpdateRequest

新增的语句用的是CreateRequest

删除的语句用的是DeleteRequest

批量操作语句用的是BulkRequest

5.2 更新数据个别字段

需求:更新999号文档,将作者名修改为CPW,标题修改为:CPW的《不能说的秘密》

    @Test@DisplayName("更新数据的个别字段")void updateNews() throws IOException {UpdateRequest<Object, Object> updateRequest = UpdateRequest.of(u -> u.index("news").id("999").doc(Map.of("author", "CPW","title", "CPW的《不能说的秘密》")));elasticsearchClient.update(updateRequest, EsNews.class);}

对比语句:

效果:

5.3 bulk(高性能批量操作)

例子:bulk的批量插入

    @Test@DisplayName("bulk的批量使用")void bulkNews() throws IOException {//数据List<EsNews> newsList = new ArrayList<>();EsNews news1 = new EsNews("777", "CPW的Elasticsearch入门1", "CPW写的Elasticsearch入门教程,整合了Springboot3", "张三", Arrays.asList("教程", "入门"),new Date(), new Date(), 1000L);EsNews news2 = new EsNews("888", "CPW的Elasticsearch入门2", "CPW写的Elasticsearch入门教程,整合了Springboot3", "李四", Arrays.asList("教程", "入门"),new Date(), new Date(), 1000L);newsList.add(news1);newsList.add(news2);//构建bulkRequest请求BulkRequest.Builder builder = new BulkRequest.Builder();for (EsNews news : newsList) {builder.operations(op -> op.index(idx -> idx.index("news").id(news.getId()).document(news)));}BulkResponse bulk = elasticsearchClient.bulk(builder.build());if (bulk.errors()) {System.out.println("存在失败的操作:");bulk.items().forEach(item -> {if (item.error() != null) {System.out.println("失败项: " + item.error().reason());}});} else {System.out.println("批量新增成功,共新增: " + bulk.items().size() + " 条");}}

需要使用到批量更新,删除,等操作直接修改builder.operations下的接口即可。

5.4 高亮查询

    @Test@DisplayName("高亮查询")void highLightNews() throws IOException {SearchRequest searchRequest = SearchRequest.of(s -> s.index("news").query(q -> q.multiMatch(m -> m.query("CPW").fields("title", "content"))).highlight(h -> h.fields("title",f -> f)//f->f启动默认配置,等同于.preTags("<em>").postTags("</em>").fields("content",f -> f).preTags("<em style='color:red'>") // 自定义高亮前缀标签.postTags("</em>")));SearchResponse<EsNews> search = elasticsearchClient.search(searchRequest, EsNews.class);List<Hit<EsNews>> hits = search.hits().hits();hits.forEach(hit->{if(hit.highlight().containsKey("title") && hit.source() != null){hit.source().setTitle(hit.highlight().get("title").get((0)));}if(hit.highlight().containsKey("content") && hit.source() != null){hit.source().setContent(hit.highlight().get("content").get((0)));}System.out.println(hit.source());});}

ES语句对比:

返回结果:

5.5 聚合查询

需求:查询每个作者,各自写了多少篇新闻。

@Test@DisplayName("聚合查询")void BucketingNews() throws IOException {SearchRequest searchRequest = SearchRequest.of(s -> s.index("news").size(0).aggregations("author_count",a -> a.terms(t -> t.field("author"))));SearchResponse<EsNews> search = elasticsearchClient.search(searchRequest, EsNews.class);List<StringTermsBucket> CountList = search.aggregations().get("author_count").sterms().buckets().array();System.out.println(CountList);}

6、【最佳实践】Elasticsearch+消息队列(RabbitMQ)+数据库(MYSQL)

实际应用

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

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

相关文章

OpenCV 官翻8 - 其他算法

文章目录高动态范围成像引言曝光序列源代码示例图像说明结果色调映射图像曝光融合附加资源高级图像拼接 API&#xff08;Stitcher 类&#xff09;目标代码说明相机模型试用指南图像拼接详解 (Python OpenCV >4.0.1)stitching_detailed如何使用背景减除方法目标代码代码解析结…

2025年一区SCI-回旋镖气动椭圆优化算法Boomerang Aerodynamic Ellipse-附Matlab免费代码

引言 本期介绍一种新的元启发式算法——回旋镖气动椭圆优化算法Boomerang Aerodynamic Ellipse Optimizer (BAEO)。该优化器的灵感来自于飞行中的回旋镖的空气动力学行为&#xff0c;明确地建模了释放角和发射力如何塑造其轨迹。于2025年7月最新发表在JCR 1区&#xff0c;中科…

Custom SRP - Custom Render Pipeline

https://catlikecoding.com/unity/tutorials/custom-srp/custom-render-pipeline/ 1. 新建 Render Pipeline 任何内容的渲染&#xff0c;最终都是要由 unity 决定在哪里&#xff0c;什么时候&#xff0c;以哪些参数进行渲染。根据目标效果的复杂程度&#xff0c;决定渲染的过程…

C语言面向对象编程

1.内核通用链表一、什么是 list_head&#xff1f;list_head 是 Linux 内核中自己实现的一种 双向循环链表 的结构&#xff0c;定义在 <linux/list.h> 中。它设计得非常轻巧、灵活&#xff0c;广泛用于内核模块、驱动、进程调度、网络协议栈等。它的关键思想是&#xff1a…

Spring Boot+Redis Zset:三步构建高可靠延迟队列系统

系统设计架构图---------------- ----------------- ---------------- | | | | | | | 生产者 |------>| Redis ZSet |------>| 定时任务消费者 | | (添加延迟任务) | | (延…

MCP vs 传统集成方案:REST API、GraphQL、gRPC的终极对比

MCP vs 传统集成方案&#xff1a;REST API、GraphQL、gRPC的终极对比 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个特…

SQL语句中锁的使用与优化

一、锁机制简介1.定义在数据库中&#xff0c;除了传统的计算资源&#xff08;如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供需要用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题&#xff0c;锁冲突也是影响数据库并…

Linux笔记1——简介安装

操作系统给用户一个操作界面&#xff0c;用户通过操作界面使用系统资源Linux内核管理控制硬件&#xff0c;和硬件打交道SCSI&#xff08;盘&#xff09;sd**;第一个*表示磁盘顺序&#xff0c;第二个*表示分区。例如&#xff1a;sda\sdb\sdc,sda1,sda2NVMe&#xff08;盘&#x…

GoLand 部署第一个项目

前言&#xff1a;Go环境部署分为两种模式&#xff0c;一种是基于GOPATH部署&#xff08;老版本&#xff09;&#xff0c;另一种是基于Module部署&#xff08;新版本v1.11开始&#xff09;。GOPATH&#xff1a;需要配置GOPATH路径&#xff0c;将GOPATH目录视为工作目录&#xff…

Mosaic数据增强介绍

1. 核心概念与目标Mosaic 是一种在计算机视觉&#xff08;尤其是目标检测任务&#xff09;中非常流行且强大的数据增强技术。它最早由 Ultralytics 的 Alexey Bochkovskiy 在 YOLOv4 中提出并推广&#xff0c;后来被广泛应用于 YOLOv5, YOLOv7, YOLOv8 等模型以及其他目标检测框…

LINUX 722 逻辑卷快照

逻辑卷快照 lvcreate -L 128M -s -n lv1-snap /dev/vg1/lv1 lvs lvscan mount -o ro /dev/vg1/lv1 /mmt/lv1-snap dmsetup ls --tree 测试 lvs /dev/vg1/lv1-snap dd if/dev/zero of/uc1/test bs1M count40 lvs /dev/vg1/lv1-snap 问题 [rootweb ~]# cd /mnt [rootweb mnt]# m…

Springboot+vue个人健康管理系统的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBoot前端框架Vue持久层框架MyBaits成功系统案例&#xff1a;代码参考数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续…

数据结构 --栈和队链

一.栈的概念一种特殊的线性表&#xff0c;只能从固定的一端插入和删除元素。栈中元素遵循先进后出的原则。二.模拟实现public class MyStack {public int size;public int[] array;public MyStack(){array new int[10];}private void grow(){array Arrays.copyOf(array,array…

文档处理控件TX Text Control系列教程:使用 C# .NET 将二维码添加到 PDF 文档

PDF 文档通常是合同、发票、证书和报告的最终格式。尽管它们在设计上是静态的&#xff0c;但用户现在希望能够与它们交互、验证信息并直接从这些文件访问数字服务。这时&#xff0c;二维码就变得至关重要。 PDF 文档中的二维码将印刷或数字内容与动态在线体验连接起来。用户只需…

Google Chrome 谷歌浏览器全部版本集合

Google Chrome 谷歌浏览器全部版本集合 Collection of all software versions of Google Chrome. 项目介绍 本项目为Google Chrome谷歌浏览器的全部版本集合&#xff0c;方便大家下载旧版本使用。 因为Gitee项目限制仓库1G大小&#xff0c;所以许多谷歌浏览器版本无法上传。…

论文略读:Towards Safer Large Language Models through Machine Unlearning

ACL 2024大型语言模型&#xff08;LLMs&#xff09;的迅猛发展展现了其在多个领域的巨大潜力&#xff0c;这主要得益于其广泛的预训练知识和出色的泛化能力。然而&#xff0c;当面对问题性提示&#xff08;problematic prompts&#xff09;时&#xff0c;LLMs 仍然容易生成有害…

深度学习 ---参数初始化以及损失函数

深度学习 —参数初始化以及损失函数 文章目录深度学习 ---参数初始化以及损失函数一&#xff0c;参数初始化1.1 固定值初始化1.1.1 全0初始化1.1.2 全1初始化1.3 任意常数初始化1.2 随机初始化一&#xff0c;参数初始化 神经网络的参数初始化是训练深度学习模型的关键步骤之一…

JS--M端事件

移动端&#xff08;Mobile 端&#xff0c;简称 M 端&#xff09;开发中&#xff0c;由于设备特性&#xff08;触摸屏、手势操作等&#xff09;&#xff0c;需要处理一些与桌面端不同的事件。这些事件主要针对触摸交互、手势识别等场景 一、触摸事件&#xff08;Touch Events&am…

Linux网络编程-tcp

tcp、udp对比&#xff1a;UDP1. 特点无连接&#xff1a;无需建立连接即可发送数据。不可靠&#xff1a;不保证数据顺序或完整性。低延迟&#xff1a;适合实时性要求高的场景。2. 应用场景视频/音频流传输&#xff08;如直播&#xff09;。DNS 查询、在线游戏。TCP1. 特点面向连…

记一次flink资源使用优化

一.现状分析 现有任务的资源配置如下&#xff0c;根据ui监控中Garbage Collection可以发现&#xff0c;此任务频繁的发生GC&#xff0c;且老年代GC时间较久二.整体memory使用分析如下Framework Heap&#xff08;框架堆内存&#xff09;用于Flink框架自身的堆内存&#xff08;如…