【ElasticSearch系列-05】SpringBoot整合elasticSearch

ElasticSearch系列整体栏目


内容链接地址
【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827
【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631
【三】ElasticSearch的高级查询Query DSLhttps://blog.csdn.net/zhenghuishengq/article/details/134159587
【四】ElasticSearch的聚合查询操作https://blog.csdn.net/zhenghuishengq/article/details/134159587
【五】SpringBoot整合elasticSearchhttps://blog.csdn.net/zhenghuishengq/article/details/134212200

SpringBoot整合elasticSearch

  • 一,SpringBoot整合ElasticSearch
    • 1,需要的依赖以及版本
    • 2,创建config配置类并测试连接
    • 3,增删改查测试
      • 3.1,索引插入数据
      • 3.2,根据id查询数据
      • 3.3,删除一条数据
    • 4,普通查询
      • 4.1,match条件查询
      • 4.2,term精确匹配
      • 4.3,prefix前缀查询
      • 4.4,通配符查询wildcard
      • 4.5,范围查询
      • 4.6,fuzzy模糊查询
      • 4.7,highlight高亮查询
    • 5,聚合查询
      • 5.1,aggs聚合查询
      • 5.2,获取最终结果

一,SpringBoot整合ElasticSearch

前面几篇讲解了es的安装,dsl语法,聚合查询等,接下来这篇主要就是讲解通过java的方式来操作es,这里选择通过springboot的方式整合ElasticSearchSearch

在学习这个整合之前,可以查看对应的官网资料:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/7.17/connecting.html

1,需要的依赖以及版本

首先创建springboot项目,然后需要的依赖如下,我前面用的是7.7.0的版本,因此这里继续使用这个版本。其他的依赖根据个人需要选择

<properties><java.version>8</java.version><elasticsearch.version>7.7.0</elasticsearch.version>
</properties>
<dependencies><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.7.0</version></dependency>
</dependencies>

2,创建config配置类并测试连接

随后创建一个config的配置类,用于连接上ElasticSearch,我这边是单机版,并没有集群

/*** 连接es的工具类*/
@Configuration
public class ElasticSearchConfig { public static final RequestOptions COMMON_OPTIONS;static {RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();COMMON_OPTIONS = builder.build();}@Beanpublic RestHighLevelClient esRestClient(){RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("xx.xx.xx.xx", 9200, "http")));return  client;}
}

在创建好了之后,可以直接在test类中进行测试,看能否连接成功

@RunWith(SpringRunner.class)
@SpringBootTest
public class StudyApplicationTests {@Resourceprivate RestHighLevelClient client;@Testpublic void contextLoads() {System.out.println(restHighLevelClient);}
}

在运行之后,如果打印出了以下这句话,表示整合成功

org.elasticsearch.client.RestHighLevelClient@7d151a

3,增删改查测试

3.1,索引插入数据

首先先创建一个users的索引,并向里面插入一条数据。插入和更新都可以用这个方法

//创建一个user索引,并且插入一条数据
@Test
public void addData() throws IOException {//创建一个索引IndexRequest userIndex = new IndexRequest("users");User user = new User();user.setId(1);user.setUsername("Tom");user.setPassword("123456");user.setAge(18);user.setSex("女");//添加数据userIndex.source(JSON.toJSONString(user), XContentType.JSON);IndexResponse response = client.index(userIndex, ElasticSearchConfig.COMMON_OPTIONS);//响应数据System.out.println(response);
}

随后再在kibana中查询这个索引,可以看到这条数据是已经插入成功的,并且索引页创建成功

在这里插入图片描述

3.2,根据id查询数据

查询id为1的数据,需要通过QueryBuild构造器查询

@Test
public void getById() throws IOException {SearchRequest request = new SearchRequest("users");SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(QueryBuilders.matchQuery("id", "1"));request.source(builder);SearchResponse response = client.search(request, RequestOptions.DEFAULT);System.out.println(response);
}

3.3,删除一条数据

删除刚刚创建的这条数据,这里直接设置id为1即可

@Test
public void deleteById() throws Exception{DeleteRequest request = new DeleteRequest("users");request.id("1");DeleteResponse delete = client.delete(request, ElasticSearchConfig.COMMON_OPTIONS);System.out.println(delete);
}

4,普通查询

这里主要是结合本人写的第三篇Query DSL的语法,通过java的方式写出依旧是先创建一个员工的信息索引,并且设置字段得我属性

PUT /employees
{"mappings": {"properties": {"name":{"type": "keyword"},"job":{"type": "keyword"},"salary":{"type": "integer"}}}
}

随后批量的插入10条数据

PUT /employees/_bulk
{ "index" : {  "_id" : "1" } }
{ "name" : "huisheng1","job":"python","salary":35000 }
{ "index" : {  "_id" : "2" } }
{ "name" : "huisheng2","job":"java","salary": 50000}
{ "index" : {  "_id" : "3" } }
{ "name" : "huisheng3","job":"python","salary":18000 }
{ "index" : {  "_id" : "4" } }
{ "name" : "huisheng4","job":"java","salary": 22000}
{ "index" : {  "_id" : "5" } }
{ "name" : "huisheng5","job":"javascript","salary":18000 }
{ "index" : {  "_id" : "6" } }
{ "name" : "huisheng6","job":"javascript","salary": 25000}
{ "index" : {  "_id" : "7" } }
{ "name" : "huisheng7","job":"c++","salary":20000 }
{ "index" : {  "_id" : "8" } }
{ "name" : "huisheng8","job":"c++","salary": 20000}
{ "index" : {  "_id" : "9" } }
{ "name" : "huisheng9","job":"java","salary":22000 }
{ "index" : {  "_id" : "10" } }
{ "name" : "huisheng10","job":"java","salary": 9000}

4.1,match条件查询

首先是分页查询,分页查询的queryDSL的语法如下

GET /employees/_search
{"query": {"match": {"job": "java"}}
}

java的语法如下

SearchRequest request = new SearchRequest("employees");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery("job", "java"));
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(response);

短语匹配的语法如下

builder.query(QueryBuilders.matchPhraseQuery("job","java"));

多字段查询的语法如下

String fields[] = {"job","name"};
builder.query(QueryBuilders.multiMatchQuery("java",fields));

queryString的语法如下

builder.query(QueryBuilders.queryStringQuery("java"));

4.2,term精确匹配

GET /employees/_search
{"query": {"term": {"job": "java"}}
}

精确匹配通过java的方式如下

builder.query(QueryBuilders.termQuery("job","java"));

4.3,prefix前缀查询

PUT /employees/_search
{"query":{"prefix":{"name":{"value":"huisheng1"}}}
}

前缀查询的java方式如下

builder.query(QueryBuilders.prefixQuery("name","huisheng1"));

4.4,通配符查询wildcard

GET /employees/_search
{"query": {"wildcard": {"job": {"value": "*py*"}}}
}

通配符查询的java方式如下

builder.query(QueryBuilders.wildcardQuery("job","py"));

4.5,范围查询

POST /employees/_search
{"query": {"range": {"salary": {"gte": 25000}}}
}

范围查询的java方式如下

builder.query(QueryBuilders.rangeQuery("salary").gte(25000));

4.6,fuzzy模糊查询

GET /employees/_search
{"query": {"fuzzy": {"job": {"value": "javb","fuzziness": 1    //表示允许错一个字}}}
}

模糊查询的java方式如下

builder.query(QueryBuilders.fuzzyQuery("job","javb").fuzziness(Fuzziness.ONE));

4.7,highlight高亮查询

GET /employees/_search
{"query": {"term": {"job": {"value": "java"}}},"highlight": {"fields": {"*":{}}}
}

高亮查询的java方式如下

builder.query(QueryBuilders.termQuery("job","java"));
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("job");
builder.highlighter(highlightBuilder);

5,聚合查询

5.1,aggs聚合查询

先通过job进行分组查询,再拿到结果后再进行stats查询,求最大值,最小值,平均值等

POST /employees/_search
{"size": 0,"aggs": {"name": {"terms": {"field": "job"},"aggs": {"stats_salary": {"stats": {"field": "salary"}}}}}
}

其java代码如下,需要注意的点就是,如果存在二级聚合,那么需要调用这个 subAggregation 方法,如果只需要聚合的结果而不需要查询的结果,可以直接在SearchSourceBuilder的实例设置为0即可。

@Test
public void toAgg() throws  Exception{//创建检索请求SearchRequest searchRequest = new SearchRequest();//指定索引searchRequest.indices("employees");//构建检索条件SearchSourceBuilder builder = new SearchSourceBuilder();//构建聚合条件TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("jobData").field("job");aggregationBuilder.subAggregation(AggregationBuilders.stats("salaryData").field("salary"));//将聚合条件加入到检索条件中builder.aggregation(aggregationBuilder);//只要聚合的结果,不需要查询的结果builder.size(0);searchRequest.source(builder);//执行检索SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);System.out.println("检索结果:" + searchResponse);
}

打印的结果如下,和预期要打印的结果是一致的

{"took":4,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":10,"relation":"eq"},"max_score":null,"hits":[]},"aggregations":{"sterms#jobData":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"java","doc_count":4,"stats#salaryData":{"count":4,"min":9000.0,"max":50000.0,"avg":25750.0,"sum":103000.0}},{"key":"c++","doc_count":2,"stats#salaryData":{"count":2,"min":20000.0,"max":20000.0,"avg":20000.0,"sum":40000.0}},{"key":"javascript","doc_count":2,"stats#salaryData":{"count":2,"min":18000.0,"max":25000.0,"avg":21500.0,"sum":43000.0}},{"key":"python","doc_count":2,"stats#salaryData":{"count":2,"min":18000.0,"max":35000.0,"avg":26500.0,"sum":53000.0}}]}}}

除了上面的state求全部的最大值,最小值等,还可以分别的求最大值,最小值,平均值,个数等,求平均值的的示例如下,需要使用到这个 AvgAggregationBuilder 构造器

AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("salaryData").field("salary");
//将聚合条件加入到检索条件中
builder.aggregation(avgAggregationBuilder);

求最大值的示例如下,需要使用到这个 MaxAggregationBuilder 构造器

MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("maxData").field("salary");
//将聚合条件加入到检索条件中builder.aggregation(maxAggregationBuilder);

求最小值的示例如下,需要使用到这个 MinAggregationBuilder 构造器

MinAggregationBuilder minAggregationBuilder = AggregationBuilders.min("minData").field("salary");
//将聚合条件加入到检索条件中
builder.aggregation(minAggregationBuilder);

求总个数的示例如下,需要使用到这个 ValueCountAggregationBuilder 构造器

ValueCountAggregationBuilder countBuilder = AggregationBuilders.count("countData").field("salary");
//将聚合条件加入到检索条件中
builder.aggregation(countBuilder);

5.2,获取最终结果

上面在查询之后,会获取 SearchResponse 的对象,这里面就值执行查询后返回的结果

SearchResponse searchResponse

随后可以直接过滤结果,通过for循环去遍历这个 getHits

SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {String sourceAsString = searchHit.getSourceAsString();Employees employees = JSON.parseObject(sourceAsString, Employees.class);System.out.println(employees);}

或者直接获取聚合操作结果的值

//获取jobData聚合。还有Avg、Max、Min等
Terms maxData = aggregations.get("jobData");
for (Terms.Bucket bucket : maxData.getBuckets()) {String keyAsString = bucket.getKeyAsString();System.out.println("job职业:" + keyAsString + " 数量==> " + bucket.getDocCount());
}

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

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

相关文章

PTA:前序序列创建二叉树

前序序列创建二叉树 题目输入格式输出格式输入样例&#xff08;及其对应的二叉树&#xff09;输出样例 代码 题目 编一个程序&#xff0c;读入用户输入的一串先序遍历字符串&#xff0c;根据此字符串建立一个二叉树&#xff08;以二叉链表存储&#xff09;。 例如如下的先序遍…

SpringCloudAlibaba - 项目完整搭建(Nacos + OpenFeign + Getway + Sentinel)

目录 一、SpringCloudAlibaba 项目完整搭建 1.1、初始化项目 1.1.1、创建工程 1.1.2、配置父工程的 pom.xml 1.1.3、创建子模块 1.2、user 微服务 1.2.1、配置 pom.xml 1.2.2、创建 application.yml 配置文件 1.2.3、创建启动类 1.2.4、测试 1.3、product 微服务 1…

如何使用CodeceptJS、Playwright和GitHub Actions构建端到端测试流水线

介绍 端到端测试是软件开发的一个重要方面&#xff0c;因为它确保系统的所有组件都能正确运行。CodeceptJS是一个高效且强大的端到端自动化框架&#xff0c;与Playwright 结合使用时&#xff0c;它成为自动化Web、移动甚至桌面 (Electron.js) 应用程序比较好用的工具。 在本文中…

代码随想录算法训练营第23期day38|动态规划理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

目录 一、动态规划理论基础 1.动态规划的解题步骤 2.动态规划应该如何debug 二、&#xff08;leetcode 509&#xff09;斐波那契数 1.递归解法 2.动态规划 1&#xff09;确定dp数组以及下标的含义 2&#xff09;确定递推公式 3&#xff09;dp数组如何初始化 4&#x…

C++虚表与虚表指针详解

类的虚表 每个包含了虚函数的类都包含一个虚表。 当一个类&#xff08;B&#xff09;继承另一个类&#xff08;A&#xff09;时&#xff0c;类B会继承类A的函数的调用权。所以如果一个基类包含了虚函数&#xff0c;那么其继承类也可调用这些虚函数&#xff0c;换句话说&…

基于ASP.NET MVC + Bootstrap的仓库管理系统

基于ASP.NET MVC Bootstrap的仓库管理系统。源码亲测可用&#xff0c;含有简单的说明文档。 适合单仓库&#xff0c;基本的仓库入库管理&#xff0c;出库管理&#xff0c;盘点&#xff0c;报损&#xff0c;移库&#xff0c;库位等管理&#xff0c;有着可视化图表。 系统采用Bo…

MySQL导入数据库报错Error Code: 2006

Error Code: 2006 - MySQL server has gone away 因为导入的某张表数据过大导致导入中途失败 , 修改max_allowed_packet 即可解决。 SET GLOBAL max_allowed_packet 1024*1024*200;

【数据结构】数组和字符串(十五):字符串匹配2:KMP算法(Knuth-Morris-Pratt)

文章目录 4.3 字符串4.3.1 字符串的定义与存储4.3.2 字符串的基本操作4.3.3 模式匹配算法0. 朴素模式匹配算法1. ADL语言2. KMP算法分析3. 手动求失败函数定义例1例2例3 4. 自动求失败函数&#xff08;C语言&#xff09;5. KMP算法&#xff08;C语言&#xff09;6. 失败函数答案…

STM32F103C8T6第二天:按键点灯轮询法和中断法、RCC、电动车报警器(振动传感器、继电器、喇叭、433M无线接收发射模块)

1. 点亮LED灯详解&#xff08;307.11&#xff09; 标号一样的导线在物理上是连接在一起的。 将 PB8 或 PB9 拉低&#xff0c;就可以实现将对应的 LED 灯点亮。常用的GPIO HAL库函数&#xff1a; void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);//I/…

产品经理入门学习(二):产品经理问题思考维度

参考引用 黑马-产品经理入门基础课程 1. 抓住核心用户 1.1 为什么要抓住核心用户 什么是用户&#xff1f; 所有和产品有关系的群体就是用户&#xff0c;他们是一群既有共性&#xff0c;又有差异的群体组合 做产品为什么要了解用户&#xff1f; 了解用户的付费点、更好的优化产…

【软考中级】软件设计师-下午题

下午题 试题一 黑洞&#xff1a;加工有输入无输出 白洞(奇迹)&#xff1a;加工有输出无输入 灰洞&#xff1a;数据流输入的加工不足以产生输出 结构化语言&#xff1a; IF *** THEN ELSE IF *** THEN ******* END IF END IF 数据流的父子图平衡&#xff0c;如果父子图平衡就不…

【CIO人物展】黄淮学院副CIO周鹏:构建数智化平台赋能学校高质量发展

周鹏 本文由黄淮学院副CIO周鹏投递并参与《2023中国数智化转型升级优秀CIO》榜单/奖项评选。丨推荐企业—锐捷网络 大数据产业创新服务媒体 ——聚焦数据 改变商业 黄淮学院是2004年经教育部批准成立的一所省属全日制普通本科高校。学校位于素有“豫州之腹地、天下之最中”之美…

地理信息系统原理-空间数据结构(7)

​四叉树编码 1.四叉树编码定义 四叉树数据结构是一种对栅格数据的压缩编码方法&#xff0c;其基本思想是将一幅栅格数据层或图像等分为四部分&#xff0c;逐块检查其格网属性值&#xff08;或灰度&#xff09;&#xff1b;如果某个子区的所有格网值都具有相同的值&#xff0…

Linux----------------Shell重定向输入输出

&#xff08;一&#xff09; 标准输入 以键盘读取用户输入的数据&#xff0c;然后再把数据拿到 Shel程序中使用。 标准输出 Shell 程序产生的数据&#xff0c;这些数据一般都是呈现到显示器上供用户浏览查看 输入输出重定向 输入方向就是数据从哪里流向程序。数据默认从键…

【使用Python编写游戏辅助工具】第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具

前言 这里是【使用Python编写游戏辅助工具】的第五篇&#xff1a;打造交互式游戏工具界面&#xff1a;PySide6/PyQT高效构建GUI工具。本文主要介绍使用PySide6来实现构建GUI工具。 在前面&#xff0c;我们实现了两个实用的游戏辅助功能&#xff1a; 由键盘监听事件触发的鼠标连…

IntelliJ IDEA 2023 最新版如何试用?IntelliJ IDEA 2023最新版试用方法及验证ja-netfilter配置成功提示

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

[极客大挑战 2019]Http 1

题目环境&#xff1a; 看起来挺花里胡哨的 F12查看源代码寻找隐藏文件 这是啥子呀&#xff0c;果然防不胜防 点击隐藏文件Secret.php 它不是来自这个地址的请求 报头&#xff1a;https://Sycsecret.buuoj.cn 需要抓包&#xff0c;在抓包前了解部分数据包参数 GET:到 Host:来自 …

ElementUI 自定义 Tree 树形控件背景

在 template 中 <div class"container"><el-tree :data"treeList" :props"defaultProps" accordion node-click"handleNodeClick" /> </div> 在 script 中 treeList: [{ id: "-1", label: "区域选…

由于flutter_app依赖于flutter_swiper>=0.0.2,不支持零安全,版本解决失败。

参考 dart3.0使用flutter_swiper报错记录 flutter_swiper package - All Versions从官网的信息可以看到 Dart3版本不兼容 最小兼容的Dart SDK版本需要2.0 Flutter SDK 版本列表Flutter SDK 版本列表 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 说明&#xff1a;因…

算法:Java构建二叉树并递归实现二叉树的前序、中序、后序遍历

先自定义一下二叉树的类&#xff1a; // Definition for a binary tree node. public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left…