springboot 整合 ElasticSearch 方法 (二)

依赖

在pom.xml文件中需要引入3个依赖, 三个都必须有并且三个依赖的版本要一致, 不然会报错.

不一定是 7.6.1 这个版本 , 只需要保证这三个依赖的版本一致就可以了.

<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.6.1</version>
</dependency>
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.6.1</version>
</dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.6.1</version>
</dependency>

配置类

用配置类的方法来配置 es, 配置文件中就 只需要写一下用户名和密码之类的就可以了, 我们用 @Value 拿到它 .

package com.es.config;import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ElasticSearchClientConfig {@Value("${elasticsearch.username}")private String username;@Value("${elasticsearch.password}")private String password;@Beanpublic RestHighLevelClient restHighLevelClient(){RestClientBuilder builder = RestClient.builder(new HttpHost("elastic-bingo.cld", 9200)); // host和ip也是一样可以写在配置文件中的// 设置用户名和密码CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password);builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));RestHighLevelClient client = new RestHighLevelClient(builder);return client;}
}

设置用户名和密码的部分参考这篇文章: ElasticSearch设置用户名和密码

如果是本地可以写 http://localhost, 拼接上端口, 可以访问这个页面就可以了.

在这里插入图片描述

实体类

实体类和普通的 mysql 的实体类是一样的.

这里没有加 id, es 会自动生成的 (不需要设置自增非空什么的, 它自己就会生成的)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Log{private String username;private String content;private Long startTime;private Long endTime;
}

@Data, @NoArgsConstructor, @AllArgsConstructor 这三个注解是使用了 lombok 工具, 如果没有用这个依赖, 还是要生成一下get, set方法以及构造函数的哦.

其他类

因为我的项目中既用了 es, 又用了 mysql, es只是用来存储日志的 .

所以为了统一, 我还是创建了 LogServiceLogServiceImpl , 没有 mapper, 怎删改查的逻辑我写在 LogServiceImpl 里了.

LogService

public interface LogService {// 插入logsvoid insertLogs(List<Log> logs);// 查找logsList<Log> searchLogs(String username, Long startTime, Long endTime);
}

LogServiceImpl

实现类中用到了 JSON.toJSONString, 别忘记引入 fastjson 依赖:

		<!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency>
@Service
public class LogServiceImpl implements LogService {@Autowiredprivate RestHighLevelClient restHighLevelClient;@Overridepublic void insertLogs(List<Log> logs) {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");// es里的批量插入try {for (Log log:logs) {bulkRequest.add(new IndexRequest("logs").source(JSON.toJSONString(log), XContentType.JSON));}restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);} catch (IOException e) {e.printStackTrace();}}@Overridepublic List<Log> searchLogs(String username, Long startTime, Long endTime) {SearchRequest searchRequest = new SearchRequest("logs"); // logs是索引名SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 用来存放查到的所有log日志数据List<Log> logs = new ArrayList<>();// 查询条件BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 查找某个范围内的时间, time是es中的字段boolQuery.filter(QueryBuilders.rangeQuery("time").gte(startTime).lte(endTime));// 精确查找某个用户, 用must函数boolQuery.must(QueryBuilders.matchQuery("username",username));searchSourceBuilder.query(boolQuery);searchRequest.source(searchSourceBuilder);try {// 发送请求SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);// 处理返回的数据, es返回的数据结构跟mysql不一样, 返回的是一个 SearchHit[] 对象, 所以这里再处理一下for (SearchHit hit: response.getHits().getHits()) {Log log = JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()), Log.class);logs.add(log);}} catch (IOException e) {e.printStackTrace();}return logs;}
}

es返回的结构

关于 es 查询返回的结构, 可以再看一下:

我们拿到的 response 的结构是这样的 (数据是我伪造的可能有出入, 大概结构是这样的):

{"took":1,"time_out":false,"_shards": {"total":1,"succesful":1,"skipped":0,"failed":0},"hits": {"total":{"value":45,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"logs","_type":"_doc","_id":"jsOFp_jdfk_operR","_score":1.0,"_source": {"username":"xiaoming","content":"I am content","startTime":20240101,"endTime":20240201}},{"_index":"logs","_type":"_doc","_id":"jswep_joerfk_opeoRR","_score":1.0,"_source": {"username":"xiaohong","content":"I am content2","startTime":20240101,"endTime":20240201}}]}
}

response.getHits().getHits() 的结构是这样的:

[{"_index":"logs","_type":"_doc","_id":"jsOFp_jdfk_operR","_score":1.0,"_source": {"username":"xiaoming","content":"I am content","startTime":20240101,"endTime":20240201}},{"_index":"logs","_type":"_doc","_id":"jswep_joerfk_opeoRR","_score":1.0,"_source": {"username":"xiaohong","content":"I am content2","startTime":20240101,"endTime":20240201}}
]

在循环里面 hit.getSourceAsMap() 拿到的结构是这样的, 只拿到了 _source 的部分:

	{"username":"xiaohong","content":"I am content2","startTime":20240101,"endTime":20240201}

测试案例

下面是一些 es 的测试案例, 作为参考.

在建测试类的时候, 不要忘记加 @RunWith(SpringRunner.class) 注解(因为配置类是写在config文件夹下面的, 需要 @Autowired 注入一起启动)

@SpringBootTest
@RunWith(SpringRunner.class)
public class EsTest {@Autowiredprivate RestHighLevelClient restHighLevelClient;//索引的创建@Testpublic void testCreateIndex() throws IOException {//1.创建索引请求CreateIndexRequest request = new CreateIndexRequest("java_test");//2.执行创建请求,请求后获得响应CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);System.out.println(createIndexResponse.isAcknowledged());}//获取索引,只能判断存不存在@Testpublic void testExistIndex() throws IOException {GetIndexRequest request = new GetIndexRequest("java_test");boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);System.out.println(exists);}//删除索引@Testpublic void testDeleteIndex() throws IOException {DeleteIndexRequest request = new DeleteIndexRequest("java_test");AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);System.out.println(response.isAcknowledged());}//添加文档@Testpublic void testAddDocument() throws IOException {//创建对象User user = new User("张三", 18);//创建请求IndexRequest request = new IndexRequest("java_test");//规则 put /java_test/_doc/1request.id("1");request.timeout(TimeValue.timeValueSeconds(1));//将数据放入请求 jsonrequest.source(JSON.toJSONString(user), XContentType.JSON);//客户端发送请求,获取响应结果IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);System.out.println(indexResponse.toString());System.out.println(indexResponse.status());}//获取文档,判断是否存在@Testpublic void testExistDocument() throws IOException {GetRequest request = new GetRequest("java_test","1");//不获取返回的_source的上下文request.fetchSourceContext(new FetchSourceContext(false));request.storedFields("_none_");boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);System.out.println(exists);}//获取文档的信息@Testpublic void testGetDocument() throws IOException {GetRequest request = new GetRequest("java_test","1");GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);String sourceAsString = response.getSourceAsString();System.out.println(response);//返回全部内容和命令是一样的System.out.println(sourceAsString);//打印文档内容}//更新文档的信息@Testpublic void testUpdateDocument() throws IOException {UpdateRequest request = new UpdateRequest("java_test","1");User user = new User("李四", 22);request.doc(JSON.toJSONString(user),XContentType.JSON);UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);System.out.println(response.status());}//删除文档记录@Testpublic void testDeleteDocument() throws IOException {DeleteRequest request = new DeleteRequest("java_test", "1");DeleteResponse deleteResponse = restHighLevelClient.delete(request, RequestOptions.DEFAULT);System.out.println(deleteResponse.status());}//真实项目一般都会批量插入数据@Testpublic void testBulkRequest() throws IOException {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");List<User> userList = new ArrayList<>();userList.add(new User("zhangan1", 18));userList.add(new User("zhangan2", 18));userList.add(new User("zhangan3", 18));userList.add(new User("lisi1", 18));userList.add(new User("lisi2", 18));userList.add(new User("lisi3", 18));//批处理请求for (int i = 0; i < userList.size(); i++) {//批量更新和批量删除,就在这里修改对应的请求就可以了bulkRequest.add(new IndexRequest("java_test").id("" + (i+1)).source(JSON.toJSONString(userList.get(i)), XContentType.JSON));}BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulkResponse.hasFailures());//是否失败,返回false 代表成功}//查询@Testpublic void testSearch() throws IOException {SearchRequest searchRequest = new SearchRequest("java_test");//构建搜索条件SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//查询条件,我们可以使用QueryBuilds工具类来实现//QueryBuilders.termQuery() 精确//QueryBuilders.matchAllQuery() 匹配所有TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "lisi1");sourceBuilder.query(termQueryBuilder);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println(JSON.toJSONString(searchResponse.getHits()));System.out.println("===============================================");for (SearchHit searchHit:searchResponse.getHits().getHits()) {System.out.println(searchHit.getSourceAsString());}}
}

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

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

相关文章

【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

阅读导航 引言一、特殊类 --- 不能被拷贝的类1. C98方式&#xff1a;2. C11方式&#xff1a; 二、特殊类 --- 只能在堆上创建对象的类三、特殊类 --- 只能在栈上创建对象的类四、特殊类 --- 不能被继承的类1. C98方式2. C11方法 总结温馨提示 引言 在面向对象编程中&#xff0…

Django框架(一)安装与创建项目

认识 Django Django是一个高级Python Web框架&#xff0c;它鼓励快速开发和简洁、实用的设计。它由经验丰富的开发人员构建&#xff0c;解决了Web开发的大部分麻烦&#xff0c;因此您可以专注于编写应用程序&#xff0c;而无需重新发明轮子。它是免费和开源的。 Django官网地…

Java笔记 --- 五、File

五、File 概述 将字符串变成File对象&#xff0c;再去使用里面的方法 父级路径&#xff1a;除了文件本身的路径 C:\Users\Desktop 子级路径&#xff1a;文件名 m.txt 常见的成员方法 判断、返回 length 只能获取文件的大小(字节数量) 创建、删除 delete方法默认只能删除…

行测-资料:1. 速算技巧、基期与现期

1、速算技巧 1.1 截位直除 1.1.1 截位 1.1.2 截谁 1.1.3 截几位 选项差距大&#xff1a; 四个选项首位均不同首位相同&#xff0c;第二位差大于首位 选项差距小&#xff1a; 首位相同且第二位差小于等于首位 例子 C&#xff0c;截两位。 C&#xff0c;截两位。 B&#xff0c;截…

JS中的try...catch

一、定义和结构 作用&#xff1a;捕获同步执行代码下的异常错误 在没有使用try...catch的情况下&#xff0c;同步代码执行遇到异常会报错&#xff0c;并中断后续代码执行&#xff1b; 在使用try...catch的情况下&#xff0c;同步代码执行遇到异常会抛出异常&#xff0c;并继续…

[Linux]HTTP状态响应码和示例

1xx&#xff1a;信息响应类&#xff0c;表示接收到请求并且继续处理 2xx&#xff1a;处理成功响应类&#xff0c;表示动作被成功接收、理解和接受 3xx&#xff1a;重定向响应类&#xff0c;为了完成指定的动作&#xff0c;必须接受进一步处理 4xx&#xff1a;客户端错误&#x…

基于ncurse的floppy_bird小游戏

1. 需求分析 将运动分解为鸟的垂直运动和杆的左右运动。 2. 概要设计 2.1 鸟运动部分 2.2 杆的运动 3. 代码实现 #include <stdio.h> #include <ncurses.h>#include <stdlib.h> #include <time.h>int vx 0; int vy 1;int bird_r; int bird_c;int…

奇怪问题说 - 测试篇

文章目录 1.什么是软件测试2.软件测试和开发的区别3.软件测试的发展&#xff1a;4.软件测试岗位5.软件测试在不同类型公司的定位6.一个优秀的软件测试人员具备的素质6.1综合能力6.2掌握自动化测试技术6.3优秀的测试用例设计能力6.4探索性思维6.5有责任感和一定的压力 7.软件测试…

物联网IOT: 风浆叶片拧紧装配及实时监测系统

某大型风电设备,通过机器人应用与精益化生产体系的融合,打造出行业领先的具备柔性生产能力的“脉动式”生产体系。同时在关键工序上。其中,在叶片装配等关键工序上使用由智能机器人代替人工,以提高生产的效率和装配质量可靠性,将六轴机器人、视觉系统、光电系统、液压、气动、伺…

AMEYA360--思瑞浦推出16通道高精度ADC—TPAFE51760

聚焦高性能模拟芯片和嵌入式处理器研发的半导体公司——思瑞浦推出全新16通道高精度ADC——TPAFE51760。 TPAFE51760内置高精度基准&#xff0c;工作温度支持-40C to 125C&#xff0c;产品广泛应用于电力自动化领域中的DTU、FTU、MU等装置。 TPAFE51760产品优势 业界领先的30V模…

2013年苏州大学837复试机试C/C++

2013年苏州大学复试机试 第一题 题目 假设有一堆数字&#xff08;小于100个&#xff09;需要对其做如下处理&#xff1a; 求平均数求标准差求方差 可用函数实现也可以不用 代码 #include <iostream> #include <sstream> //字符串流 #include <cmath> …

拦截器的简单使用

拦截器的简单使用 拦截器的使用创建拦截器preHandle 目标方法执行前执行postHandle 目标方法执行后执行afterCompletion 视图渲染后执行 拦截器使用场景返回值注册拦截器运用拦截器 拦截器的使用 创建拦截器 首先,我们需要创建一个拦截器器的类,并且需要继承自HandlerIntercep…

Linux服务器配置与管理(第二次实验)

实验目的及具体要求 目的 1.掌握基于命令行的文件操作 2.掌握基于命令行的目录操作 3.掌握用户账户的命令行操作 4.掌握组账户的命令行操作 5.熟悉磁盘分区操作 6.掌握调整优先级的方法 具体要求 1.掌握基于命令行的文件和目录操作 ①创建测试目录 ②创建文件 ③复…

细数语音识别中的几个former

随着Transformer在人工智能领域掀起了一轮技术革命&#xff0c;越来越多的领域开始使用基于Transformer的网络结构。目前在语音识别领域中&#xff0c;Tranformer已经取代了传统ASR建模方式。近几年关于ASR的研究工作很多都是基于Transformer的改进&#xff0c;本文将介绍其中应…

python 基础知识点(蓝桥杯python科目个人复习计划25)

今日复习内容&#xff1a;基础算法中的进制转换 1.任意进制转十进制 &#xff08;1&#xff09; 基数&#xff1a;表示奇数数字符号的个数 10进制&#xff1a;0--9&#xff0c;基数为1016进制&#xff1a;0--9&#xff0c;A--F&#xff0c;基数为16 &#xff08;2&#xff…

计算机找不到ucrtbased.dll无法运行程序,分享5种有效的解决方法

当计算机系统在运行过程中无法找到ucrtbased.dll这个特定的动态链接库文件时&#xff0c;可能会引发一系列的问题和故障现象。ucrtbased.dll是Windows操作系统中一个至关重要的组件&#xff0c;它包含了C运行时库的核心函数&#xff0c;对于许多应用程序特别是基于Microsoft Vi…

【论文+App试玩+图像到视频】2311.Animate-anyone:上传1张图片为任何人制作动画(用于角色动画的一致且可控的图像到视频合成)(暂未开源)

项目主页&#xff1a;https://humanaigc.github.io/animate-anyone/ 论文: Animate Anyone: Consistent and Controllable Image-to-Video Synthesis for Character Animation 摩尔线程复现代码&#xff1a;https://github.com/MooreThreads/Moore-AnimateAnyone 摩尔windows一…

第9章 多线程

第9章 多线程 学习目标 了解进程和线程的区别 能够理解并发与并行的区别 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 能够解释安全问题的出现的原因 能够使用同步代码块解决线程安全问题 能够使用同步方法解决线程安全问题…

多维时序 | Matlab实现WOA-TCN-Multihead-Attention鲸鱼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现WOA-TCN-Multihead-Attention鲸鱼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现WOA-TCN-Multihead-Attention鲸鱼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料 效…

C++核心编程:C++ 中的引用 笔记

2.引用 2.1 引用的基本使用 - 作用&#xff1a;给变量起别名 - 语法&#xff1a;数据类型 &别名 原名 #include<iostream> using namespace std; int main() {// 引用基本语法// 数据类型 &别名 原名int a 10;// 创建引用int &ref_a a;cout<<&qu…