从零搭建Spring Boot脚手架(7):Elasticsearch应该独立服务
1. Spring Data Elasticsearch
Spring Data Elasticsearch是Spring Data项目的子项目,提供了Elasticsearch与Spring的集成。实现了Spring Data Repository风格的Elasticsearch文档交互风格,让你轻松进行Elasticsearch客户端开发。
2. 个人的一些看法
应粉丝要求特地将Elasticsearch整合到Spring Boot 中去。本来打算整合到kono脚手架中,但是转念一想这样并不是非常合适,一般搜索建议作为一个独立的平台运作,小公司可作为一个独立的服务,大公司可作为一个搜索中台。一般我认为虽然Elasticsearch提供了搜索功能,大部分情况下我们并不像常规的关系型数据库一样进行直接写入,而是通过同步的方式进行同步或者预热写入数据。
具体的架构不是本文要讲的,在ES的CSDN官方博客里面有比较具体的解决方案。本文是在你已经搭建好Elasticsearch集群的前提下进行的。
2. 版本对应
相关项目的版本对应关系如下:
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Boot |
|---|---|---|---|
| Neumann | 4.0.x | 7.6.2 | 2.3.x |
| Moore | 3.2.x | 6.8.6 | 2.2.x |
| Lovelace | 3.1.x | 6.2.2 | 2.1.x |
| Kay | 3.0.x | 5.5.0 | 2.0.x |
| Ingalls | 2.1.x | 2.4.0 | 1.5.x |
根据我平常的做法,我选择Elasticsearch 7.6.2和Spring Boot 2.3.3作为版本基准进行集成。
3. 依赖引入及配置
只需要引入下面的依赖就可以集成Elasticsearch :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
关于配置有两种一种面向传统的Restful:
spring:
elasticsearch:
rest:
# 逗号分隔的Elasticsearch实例使用的列表
uris: http://localhost:9200
# 链接超时时间
connection-timeout:
# 读取超时时间
read-timeout:
# ES 用户名
username:
# ES 密码
password:
如果你都采用默认的配置,可以什么都不配置,包括
uris。
另一种面向反应式:
spring:
data:
elasticsearch:
client:
# 反应式相关的配置
reactive:
# 端点
endpoints:
connection-timeout:
max-in-memory-size:
socket-timeout:
use-ssl:
username:
password:
这里配合的是Spring Webflux反应式框架,我个人其实更加倾向于此,但是作为目前的主流还是选择了第一种。
务必保证
spring.data.elasticsearch.repositories.enabled = true,否则无法使用Spring Data Repository模式。
4. 操作
这里演示面向传统的Restful,一共有两种风格。假如我们向写入了Blog:
{
"blogId": "132435553",
"blogTitle": "脚手架集成elasticsearch",
"author": "felord",
"content": "全称为Object Storage Service,也叫对象存储服务,是一种解决和处理离散单元的方法,可提供基于分布式系统之上的对象形式的数据存储服务,具有可拓展、可管理、低成本等特点,支持中心和边缘存储,能够实现存储需求的弹性伸缩,主要应用于海量数据管理的各类场景。\n\n这概念真是够难以理解的。简单说点我知道的吧,平常我们的文件地址都是 /User/felord/video/xxx.mp4的目录树结构,系统先要找到User,然后一级一级往下找一直到目标为止,这是一种结构化的存储方式。对象存储就不一样了,所有的文件都放在一个特定的池子里,只不过文件的携带有它自己的元信息,通过元信息去检索文件。",
"url": "https://felord.cn/my-spring-boot-day7.html",
"publishedTime": "2020-08-30T22:17:40"
}
对应的POJO对象为:
/**
* @author felord.cn
* @since 2020/8/30 16:10
*/
@Document(indexName = "blogs")
@Data
public class Blog {
@Id
private String blogId;
private String blogTitle;
private String author;
private String content;
private String url;
@Field(type = FieldType.Date,format = DateFormat.date_hour_minute_second)
private LocalDateTime publishedTime;
}
@Document用来标记文档对象,包含了该文档的一些元信息,索引副本数,分片数。@Id文档的标识符。@Field文档字段的一些元信息配置,类型、名称、分词器等等。
主要有以上三种,还有其它的一些注解标记,这里不再讲述。
4.1 ElasticsearchRestTemplate
RedisTemplate相信你已经不陌生了,同样的,Spring Data Elasticsearch提供了ElasticsearchRestTemplate来操作Elasticsearch,增删改查应有尽有。这里演示进行复杂的Criteria查询。
从blogs索引中查询blogId为132435553而且包含elastic词汇的标题的文档,同时查询词汇高亮
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void testTemplate() {
// 构造条件
Criteria criteria = Criteria.where(new SimpleField("blogId"))
.is("132435553")
.and(new SimpleField("blogTitle"))
.contains("elastic");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// 高亮
HighlightBuilder blogTitle = SearchSourceBuilder.highlight().field("blogTitle");
HighlightQuery highlightQuery = new HighlightQuery(blogTitle);
criteriaQuery.setHighlightQuery(highlightQuery);
SearchHits<Blog> blogSearchHits = elasticsearchRestTemplate.search(criteriaQuery, Blog.class);
blogSearchHits.getSearchHits().forEach(System.out::println);
}
4.2 Spring Data Repository
Spring Data Repository的核心接口是Repository。这个接口需要领域类(比如上面的Blog)跟领域类的ID类型作为参数。这个接口主要是让你能知道继承这个类的接口的类型。CrudRepository提供了对被管理的实体类的一些常用增删改查方法。那么针对Elasticsearch提供了各种特色的接口:
Repository模式提供了一种利用方法名称进行条件构造的查询方式。
这种方式好处就是语义化,坏处就是方法名称可能非常的长。对于4.1中的例子我们可以简化为:
/**
* @author felord.cn
* @since 2020/8/30 21:32
*/
public interface BlogRepository extends ElasticsearchRepository<Blog,String> {
@Highlight(fields = {
@HighlightField(name = "blogTitle")
})
List<SearchHit<Blog>> searchBlogByBlogIdAndBlogTitleContains(String blogId, String titleContains);
}
另一种是采用注解方式,使用@Query注解,比如我们根据blogId进行查询我们可以这么写:
@Query("{\"match\": {\"blogId\": \"?0\" }}")
// @Query("{\"match\": {\"blogId\":{\"query\": \"?0\"}}}")
Blog searchById(String blogId);
这个优点就是更加灵活,而且写法也更加随意简单;缺点就是需要熟悉Spring Data Elasticsearch以及Elasticsearch的查询语法,有一定的学习成本。
总结
以上就是简单的Spring Data Elasticsearch入门,对于使用Elasticsearch的项目来说,一般都具有了很大的数据量,所以要根据业务的需要进行具体的设计,Spring Data Elasticsearch能让我们非常方便进行搜索操作,如果你在使用中遇到什么问题可以通过公众号:码农小胖哥留言进行讨论。
关注公众号:Felordcn 获取更多资讯
从零搭建Spring Boot脚手架(7):Elasticsearch应该独立服务的更多相关文章
- 从零搭建Spring Boot脚手架(1):开篇以及技术选型
1. 前言 目前Spring Boot已经成为主流的Java Web开发框架,熟练掌握Spring Boot并能够根据业务来定制Spring Boot成为一个Java开发者的必备技巧,但是总是零零碎碎 ...
- 从零搭建Spring Boot脚手架(2):增加通用的功能
1. 前言 今天开始搭建我们的kono Spring Boot脚手架,首先会集成Spring MVC并进行定制化以满足日常开发的需要,我们先做一些刚性的需求定制,后续再补充细节.如果你看了本文有什么问 ...
- 从零搭建Spring Boot脚手架(3):集成mybatis
1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文集成了一些基础的功能,比如统一返回体.统一异常处理.快速类型转换.参数校验等常用必备功能,并编写了一些单元测试进行验证,今天 ...
- 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper
1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文把国内最流行的ORM框架Mybatis也集成了进去.但是很多时候我们希望有一些开箱即用的通用Mapper来简化我们的开发.我 ...
- 从零搭建Spring Boot脚手架(7):整合OSS作为文件服务器
1. 前言 文件服务器是一个应用必要的组件之一.最早我搞过FTP,然后又用过FastDFS,接私活的时候我用MongoDB也凑合凑合.现如今时代不同了,开始流行起了OSS. Gitee: https: ...
- 从零搭建Spring Boot脚手架(6):整合Redis作为缓存
1. 前言 上一文我们整合了Mybatis Plus,今天我们会把缓存也集成进来.缓存是一个系统应用必备的一种功能,除了在减轻数据库的压力之外.还在存储一些短时效的数据场景中发挥着重大作用,比如存储用 ...
- 从零搭建Spring Boot脚手架(5):整合 Mybatis Plus
1. 前言 在上一文中我根据Mybatis中Mapper的生命周期手动实现了一个简单的通用Mapper功能,但是遗憾的是它缺乏实际生产的检验.因此我选择更加成熟的一个Mybatis开发增强包.它就是已 ...
- 使用IDEA搭建Spring Boot入门项目
简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...
- Spring Boot系列学习文章(一) -- Intellij IDEA 搭建Spring Boot项目
前言: 最近做的一个项目是用Spring Boot来做的,所以把工作中遇到的一些知识点.问题点整理一下,做成一系列学习文章,供后续学习Spring Boot的同仁们参考,我也是第一次接触Spring ...
随机推荐
- selenium定位方法(一)
selenium定位方法-(一) 1.定位页面元素的方式(By类的方法) 1)id定位:通过页面元素的id属性值来定位一个页面元素 注意事项:如果每次刷新网页之后元素的id属性值都不同,说 ...
- 第四篇Scrum冲刺博客--Interesting-Corps
第四篇Scrum冲刺博客 站立式会议 1.会议照片 2.队友完成情况 团队成员 昨日完成 今日计划 鲍鱼铭 搜索页面跳转.设计及布局实现 音乐详情页面跳转.设计及布局实现设计 叶学涛 编写设置页面 编 ...
- 第6篇 Scrum 冲刺博客
1.站立会议 照骗 进度 成员 昨日完成任务 今日计划任务 遇到的困难 钟智锋 重构游戏逻辑代码 改写部分客户端代码,制作单机版 庄诗楷 进行了相关的装饰改进 与其他部分合成完成游戏 合成遇到bug, ...
- 开始System.out.println();
第一篇博客 我在逛别人的博客的时候,发现他们有些内容是写他们自己的人生,有些是关于技术方面的个人观点分享探讨,每当看到好的文章的时候,我已经习惯的去点击收藏.有的时候我也在想,我为什么就不能做一个输出 ...
- 做seo如何选择一个好的标题
http://www.wocaoseo.com/thread-86-1-1.html 我们常说人要红妆马配鞍,那么对于seo来说,网站的标题也是很重要的,如何写好标题呢?只要注意以下几点就行了. 首先 ...
- Qt QString字符串分割、截取
在做项目中不可避免的会使用到一串字符串中的一段字符,因此常常需要截取字符串. 有两种方式可以解决这个问题: 方法一:QString分割字符串: QString date=dateEdit.toStri ...
- Redis操作及集群搭建以及高可用配置
NoSQL - Redis 缓存技术 Redis功能介绍 数据类型丰富 支持持久化 多种内存分配及回收策略 支持弱事务 支持高可用 支持分布式分片集群 企业缓存产品介绍 Memcached: 优点:高 ...
- React状态管理相关
关于React状态管理的一些想法 我最开始使用React的时候,那个时候版本还比较低(16版本以前),所以状态管理都是靠React自身API去进行管理,但当时最大的问题就是跨组件通信以及状态同步和状态 ...
- Python开发的入门教程(八)-迭代
介绍 本文主要介绍Python中迭代的基本知识和使用 什么是迭代 在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Ite ...
- Java 与 Mysql连接,并分页显示
这是我第一个上规模的Java项目,我们必须在一周内完成的作业,零基础学习Java,网上收集了很多资料,逐渐对面向对象的思想有所了解,但还是半灌水,后期打算结合项目系统地学习一遍Java.老师布置的任务 ...