标签:ElasticSearch8.Kibana8;

一、简介

Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引擎,适用于各种数据类型,数字、文本、地理位置、结构化数据、非结构化数据;

在实际的工作中,历经过Elasticsearch从6.07.0的版本升级,而这次SpringBoot3和ES8.0的集成,虽然脚本的语法变化很小,但是Java客户端的API语法变化很大;

二、环境搭建

1、下载安装包

需要注意的是,这些安装包的版本要选择对应的,不然容易出问题;

软件包:elasticsearch-8.8.2-darwin-x86_64.tar.gz
分词器工具:elasticsearch-analysis-ik-8.8.2.zip
可视化工具:kibana-8.8.2-darwin-x86_64.tar.gz

2、服务启动

不论是ES还是Kibana,在首次启动后,会初始化很多配置文件,可以根据自己的需要做相关的配置调整,比如常见的端口调整,资源占用,安全校验等;

1、启动ES
elasticsearch-8.8.2/bin/elasticsearch 本地访问:localhost:9200 2、启动Kibana
kibana-8.8.2/bin/kibana 本地访问:http://localhost:5601 # 3、查看安装的插件
http://localhost:9200/_cat/plugins -> analysis-ik 8.8.2

三、工程搭建

1、工程结构

2、依赖管理

starter-elasticsearch组件中,实际上依赖的是elasticsearch-java组件的8.7.1版本;

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>${spring-boot.version}</version>
</dependency>

3、配置文件

在上面环境搭建的过程中,已经禁用了用户和密码的登录验证,配置ES服务地址即可;

spring:
# ElasticSearch配置
elasticsearch:
uris: localhost:9200

四、基础用法

1、实体类

通过DocumentField注解描述ES索引结构的实体类,注意这里JsonIgnoreProperties注解,解决索引中字段和实体类非一一对应的而引起的JSON解析问题;

@JsonIgnoreProperties(ignoreUnknown = true)
@Document(indexName = "contents_index", createIndex = false)
public class ContentsIndex implements Serializable { private static final long serialVersionUID=1L; @Field(type= FieldType.Integer)
private Integer id; @Field(type= FieldType.Keyword)
private String title; @Field(type= FieldType.Keyword)
private String intro; @Field(type= FieldType.Text)
private String content; @Field(type= FieldType.Integer)
private Integer createId; @Field(type= FieldType.Keyword)
private String createName; @Field(type= FieldType.Date,format = DateFormat.date_hour_minute_second)
private Date createTime;
}

2、初始化索引

基于ElasticsearchTemplate类和上述实体类,实现索引结构的初始化,并且将tb_contents表中的数据同步到索引中,最后通过ID查询一条测试数据;

@Service
public class ContentsIndexService {
private static final Logger log = LoggerFactory.getLogger(ContentsIndexService.class); @Resource
private ContentsService contentsService ;
@Resource
private ElasticsearchTemplate template ; /**
* 初始化索引结构和数据
*/
public void initIndex (){
// 处理索引结构
IndexOperations indexOps = template.indexOps(ContentsIndex.class);
if (indexOps.exists()){
boolean delFlag = indexOps.delete();
log.info("contents_index exists,delete:{}",delFlag);
indexOps.createMapping(ContentsIndex.class);
} else {
log.info("contents_index not exists");
indexOps.createMapping(ContentsIndex.class);
}
// 同步数据库表记录
List<Contents> contentsList = contentsService.queryAll();
if (contentsList.size() > 0){
List<ContentsIndex> contentsIndexList = new ArrayList<>() ;
contentsList.forEach(contents -> {
ContentsIndex contentsIndex = new ContentsIndex() ;
BeanUtils.copyProperties(contents,contentsIndex);
contentsIndexList.add(contentsIndex);
});
template.save(contentsIndexList);
}
// ID查询
ContentsIndex contentsIndex = template.get("10",ContentsIndex.class);
log.info("contents-index-10:{}",contentsIndex);
}
}

3、仓储接口

继承ElasticsearchRepository接口,可以对ES这种特定类型的存储库进行通用增删改查操作;在测试类中对该接口的方法进行测试;

// 1、接口定义
public interface ContentsIndexRepository extends ElasticsearchRepository<ContentsIndex,Long> {
} // 2、接口测试
public class ContentsIndexRepositoryTest {
@Autowired
private ContentsIndexRepository contentsIndexRepository; @Test
public void testAdd (){
// 单个新增
contentsIndexRepository.save(buildOne());
// 批量新增
contentsIndexRepository.saveAll(buildList()) ;
} @Test
public void testUpdate (){
// 根据ID查询后再更新
Optional<ContentsIndex> contentsOpt = contentsIndexRepository.findById(14L);
if (contentsOpt.isPresent()){
ContentsIndex contentsId = contentsOpt.get();
System.out.println("id=14:"+contentsId);
contentsId.setContent("update-content");
contentsId.setCreateTime(new Date());
contentsIndexRepository.save(contentsId);
}
} @Test
public void testQuery (){
// 单个ID查询
Optional<ContentsIndex> contentsOpt = contentsIndexRepository.findById(1L);
if (contentsOpt.isPresent()){
ContentsIndex contentsId1 = contentsOpt.get();
System.out.println("id=1:"+contentsId1);
}
// 批量ID查询
Iterator<ContentsIndex> contentsIterator = contentsIndexRepository
.findAllById(Arrays.asList(10L,12L)).iterator();
while (contentsIterator.hasNext()){
ContentsIndex contentsIndex = contentsIterator.next();
System.out.println("id="+contentsIndex.getId()+":"+contentsIndex);
}
} @Test
public void testDelete (){
contentsIndexRepository.deleteById(15L);
contentsIndexRepository.deleteById(16L);
}
}

4、查询语法

无论是ElasticsearchTemplate类还是ElasticsearchRepository接口,都是对ES常用的简单功能进行封装,在实际使用时,复杂的查询语法还是依赖ElasticsearchClient和原生的API封装;

这里主要演示七个查询方法,主要涉及:ID查询,字段匹配,组合与范围查询,分页与排序,分组统计,最大值查询和模糊匹配;更多的查询API还是要多看文档中的案例才行;

public class ElasticsearchClientTest {

    @Autowired
private ElasticsearchClient client ; @Test
public void testSearch1 () throws IOException {
// ID查询
GetResponse<ContentsIndex> resp = client.get(
getReq ->getReq.index("contents_index").id("7"), ContentsIndex.class);
if (resp.found()){
ContentsIndex contentsIndex = resp.source() ;
System.out.println("contentsIndex-7:"+contentsIndex);
}
} @Test
public void testSearch2 () throws IOException {
// 指定字段匹配
SearchResponse<ContentsIndex> resp = client.search(searchReq -> searchReq.index("contents_index")
.query(query -> query.match(field -> field
.field("createName").query("张三"))),ContentsIndex.class);
printResp(resp);
} @Test
public void testSearch3 () throws IOException {
// 组合查询:姓名和时间范围
Query byName = MatchQuery.of(field -> field.field("createName").query("王五"))._toQuery();
Query byTime = RangeQuery.of(field -> field.field("createTime")
.gte(JsonData.of("2023-07-10T00:00:00"))
.lte(JsonData.of("2023-07-12T00:00:00")))._toQuery();
SearchResponse<ContentsIndex> resp = client.search(searchReq -> searchReq.index("contents_index")
.query(query -> query.bool(boolQuery -> boolQuery.must(byName).must(byTime))),ContentsIndex.class);
printResp(resp);
} @Test
public void testSearch4 () throws IOException {
// 排序和分页,在14条数据中,根据ID倒序排列,从第5条往后取4条数据
SearchResponse<ContentsIndex> resp = client.search(searchReq -> searchReq.index("contents_index")
.from(5).size(4)
.sort(sort -> sort.field(sortField -> sortField.field("id").order(SortOrder.Desc))),ContentsIndex.class);
printResp(resp);
} @Test
public void testSearch5 () throws IOException {
// 根据createId分组统计
SearchResponse<ContentsIndex> resp = client.search(searchReq -> searchReq.index("contents_index")
.aggregations("createIdGroup",agg -> agg.terms(term -> term.field("createId"))),ContentsIndex.class);
Aggregate aggregate = resp.aggregations().get("createIdGroup");
LongTermsAggregate termsAggregate = aggregate.lterms();
Buckets<LongTermsBucket> buckets = termsAggregate.buckets();
for (LongTermsBucket termsBucket : buckets.array()) {
System.out.println(termsBucket.key() + " : " + termsBucket.docCount());
}
} @Test
public void testSearch6 () throws IOException {
// 查询最大的ID
SearchResponse<ContentsIndex> resp = client.search(searchReq -> searchReq.index("contents_index")
.aggregations("maxId",agg -> agg.max(field -> field.field("id"))),ContentsIndex.class);
for (Map.Entry<String, Aggregate> entry : resp.aggregations().entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue().max().value());
}
} @Test
public void testSearch7 () throws IOException {
// 模糊查询title字段,允许1个误差
Query byContent = FuzzyQuery.of(field -> field.field("title").value("设计").fuzziness("1"))._toQuery();
SearchResponse<ContentsIndex> resp = client.search(
searchReq -> searchReq.index("contents_index").query(byContent),ContentsIndex.class);
printResp(resp);
} private void printResp (SearchResponse<ContentsIndex> resp){
TotalHits total = resp.hits().total();
System.out.println("total:"+total);
List<Hit<ContentsIndex>> hits = resp.hits().hits();
for (Hit<ContentsIndex> hit: hits) {
ContentsIndex contentsIndex = hit.source();
System.out.println(hit.id()+":"+contentsIndex);
}
}
}

五、参考源码

文档仓库:
https://gitee.com/cicadasmile/butte-java-note 源码仓库:
https://gitee.com/cicadasmile/butte-spring-parent

SpringBoot3集成ElasticSearch的更多相关文章

  1. springboot集成elasticsearch

    在基础阶段学习ES一般是首先是 安装ES后借助 Kibana 来进行CURD 了解ES的使用: 在进阶阶段可以需要学习ES的底层原理,如何通过Version来实现乐观锁保证ES不出问题等核心原理: 第 ...

  2. 使用Logstash同步数据至Elasticsearch,Spring Boot中集成Elasticsearch实现搜索

    安装logstash.同步数据至ElasticSearch 为什么使用logstash来同步,CSDN上有一篇文章简要的分析了以下几种同步工具的优缺点:https://blog.csdn.net/la ...

  3. SpringBoot 集成 Elasticsearch

    前面在 ubuntu 完成安装 elasticsearch,现在我们SpringBoot将集成elasticsearch. 1.创建SpringBoot项目 我们这边直接引入NoSql中Spring ...

  4. zeebe 集成elasticsearch exporter

    zeebe 目前还在一直的开发中,同时一些变动还是挺大的,比如simple monitor 的以前是不需要配置HazelcastExporter的 估计是为了进行集群功能处理,新添加的,以前写的配置基 ...

  5. Elasticsearch教程(二)java集成Elasticsearch

    1.添加maven <!--tika抽取文件内容 --> <dependency> <groupId>org.apache.tika</groupId> ...

  6. SpringBoot 2.2.2集成ElasticSearch 7.5.1

    前言:现在公司有一个项目要用到检索功能,检索上面现在最常用的是Solr/ES,最后经过对比选择了ElasticSearch开源组件包,因为这个是公司的一个产品项目,技术版本当然要用最新的啦,最后完全确 ...

  7. Spring Boot 集成 Elasticsearch 实战

    最近有读者问我能不能写下如何使用 Spring Boot 开发 Elasticsearch(以下简称 ES) 相关应用,今天就讲解下如何使用 Spring Boot 结合 ES. 可以在 ES 官方文 ...

  8. Atlas2.2.0编译、安装及使用(集成ElasticSearch,导入Hive数据)

    1.编译阶段 组件信息: 组件名称 版本 Atals 2.2.0 HBase 2.2.6 Hive 3.1.2 Hadoop 3.1.1 Kafka 2.11_2.4.1 Zookeeper 3.6. ...

  9. Spring集成ElasticSearch搜索引擎

    目录 前期安装 Maven支持库安装 添加log4j的配置文件 创建Client客户端 实现增删改查以及符合查询 实现查询数据 实现添加数据 实现删除数据 实现修改数据 实现复合查询数据 Elasti ...

  10. spark 集成elasticsearch

    pyspark读写elasticsearch依赖elasticsearch-hadoop包,需要首先在这里下载,版本号可以通过自行修改url解决. """ write d ...

随机推荐

  1. 【Qt 6】读写剪贴板

    剪贴板是个啥就不用多介绍了,最直观的功能是实现应用程序之间数据共享.就是咱们常说的"复制"."粘贴"功能. 在 Qt 中,QClipboard 类提供了相关 A ...

  2. docker安装带postgis插件的postgresql 数据库

    最初直接拉取的postgresql 数据,在导入 .bakup 文件时始终会报错,最后才想到该数据库默认不带postgis空间组件 一.拉取镜像 这里我们拉取postgres 和 gis 组合的镜像 ...

  3. bootstrap treeview基本运用

    虽然现在有了很多新的前端框架,但是有的时候我们做一个不需要任何其他js编译环境就可以运行的项目,那还是的使用一些老式技术,接下来就来回顾一些bootstrap treeview + jquery的使用 ...

  4. python -----类反射

    #反射#描述:反射就是指在程序运行时,动态的去确定对象的类型,并且可以通过字符串的形式去调用对应的属性# ,方法,导入模块,是一种基于字符串的事情驱动# class User:# def __init ...

  5. 【jmeter】测试socket接口的简单应用

    一.场景 有一天开发问我,有没有什么工具可以测试socket,tcp,当时有点懵,这种需求还是少见 二.方法 使用Jmeter可以进行相关的测试 三.创建服务端环境 使用python搞个socket服 ...

  6. 文档在线预览(三)使用js前端实现word、excel、pdf、ppt 在线预览

    @ 目录 实现方案 一.docx文件实现前端预览 1.docx-preview 2.Mammoth 二.PDF文件实现前端预览 1.pdf.js 2.pdfobject.js 3.vue-pdf 4. ...

  7. ARC142

    ARC142 考试情况:一眼订正,鉴定为做出前三题. A - Reverse and Minimize 分析题目性质可得三种情况: \(K\) 末尾有 \(0\) 最多只有 \(K\) 本身一个答案. ...

  8. 在Transformers 中使用约束波束搜索引导文本生成

    引言 本文假设读者已经熟悉文本生成领域波束搜索相关的背景知识,具体可参见博文 如何生成文本: 通过 Transformers 用不同的解码方法生成文本. 与普通的波束搜索不同,约束 波束搜索允许我们控 ...

  9. 做副业的我很迷茫,但ChatGPT却治好了我——AI从业者被AI模型治愈的故事

    迷茫,无非就是不知道自己要做什么,没有目标,没有方向. 当有一个明确的目标时,往往干劲十足.但做副业过程中,最大的问题往往就是 不知道自己该干什么. 干什么?怎么干?干到什么程度?这是做副业(甚至任何 ...

  10. 【HMS Core】Health Kit云测数据接入相关问题

    ​[问题描述1] 1.由于存在IOS.android.微信小程序,计划接入"云侧数据开放服务",使用模式为我们自己的服务端去同步华为健康数据,终端通过服务端获取最新的数据. 2.在 ...