Spring Boot 集成 ElasticSearch

1 加入依赖

首先创建一个项目,在项目中加入 ES 相关依赖,具体依赖如下所示:

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

2 创建 ES 配置

在配置文件 application.properties 中配置 ES 的相关参数,具体内容如下:

elasticsearch.host=localhost
elasticsearch.port=9200
elasticsearch.connTimeout=3000
elasticsearch.socketTimeout=5000
elasticsearch.connectionRequestTimeout=500

其中指定了 ES 的 host 和端口以及超时时间的设置,另外我们的 ES 没有添加任何的安全认证,因此 username 和 password 就没有设置。

然后在 config 包下创建 ElasticsearchConfiguration 类,会从配置文件中读取到对应的参数,接着申明一个 initRestClient 方法,返回的是一个 RestHighLevelClient,同时为它添加 @Bean(destroyMethod = “close”) 注解,当 destroy 的时候做一个关闭,这个方法主要是如何初始化并创建一个 RestHighLevelClient。

@Configuration
public class ElasticsearchConfiguration {@Value("${elasticsearch.host}")private String host;@Value("${elasticsearch.port}")private int port;@Value("${elasticsearch.connTimeout}")private int connTimeout;@Value("${elasticsearch.socketTimeout}")private int socketTimeout;@Value("${elasticsearch.connectionRequestTimeout}")private int connectionRequestTimeout;@Bean(destroyMethod = "close", name = "client")public RestHighLevelClient initRestClient() {RestClientBuilder builder = RestClient.builder(new HttpHost(host, port)).setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(connTimeout).setSocketTimeout(socketTimeout).setConnectionRequestTimeout(connectionRequestTimeout));return new RestHighLevelClient(builder);}
}

3 定义文档实体类

首先在 constant 包下定义常量接口,在接口中定义索引的名字为 user:

public interface Constant {String INDEX = "user";
}

然后在 document 包下创建一个文档实体类:

public class UserDocument {private String id;private String name;private String sex;private Integer age;private String city;// 省略 getter/setter
}

4 ES 基本操作

在这里主要介绍 ES 的索引、文档、搜索相关的简单操作,在 service 包下创建 UserService 类。

4.1 索引操作

在创建索引的时候可以在 CreateIndexRequest 中设置索引名称、分片数、副本数以及 mappings,在这里索引名称为 user,分片数 number_of_shards 为 1,副本数 number_of_replicas 为 0,具体代码如下所示:

public boolean createUserIndex(String index) throws IOException {CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);createIndexRequest.settings(Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0));createIndexRequest.mapping("{\n" +"  \"properties\": {\n" +"    \"city\": {\n" +"      \"type\": \"keyword\"\n" +"    },\n" +"    \"sex\": {\n" +"      \"type\": \"keyword\"\n" +"    },\n" +"    \"name\": {\n" +"      \"type\": \"keyword\"\n" +"    },\n" +"    \"id\": {\n" +"      \"type\": \"keyword\"\n" +"    },\n" +"    \"age\": {\n" +"      \"type\": \"integer\"\n" +"    }\n" +"  }\n" +"}", XContentType.JSON);CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);return createIndexResponse.isAcknowledged();
}

通过调用该方法,就可以创建一个索引 user,索引信息如下:
在这里插入图片描述
关于 ES 的 Mapping会专门出一篇文章进行讲解

4.2 删除索引

在 DeleteIndexRequest 中传入索引名称就可以删除索引,具体代码如下所示:

public Boolean deleteUserIndex(String index) throws IOException {DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);return deleteIndexResponse.isAcknowledged();
}

介绍完索引的基本操作,下面介绍文档的相关操作:

4.3 文档操作

在这里演示下创建文档、批量创建文档、查看文档、更新文档以及删除文档:

4.3.1 创建文档

创建文档的时候需要在 IndexRequest 中指定索引名称,id 如果不传的话会由 ES 自动生成,然后传入 source,具体代码如下:

public Boolean createUserDocument(UserDocument document) throws Exception {UUID uuid = UUID.randomUUID();document.setId(uuid.toString());IndexRequest indexRequest = new IndexRequest(Constant.INDEX).id(document.getId()).source(JSON.toJSONString(document), XContentType.JSON);IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);return indexResponse.status().equals(RestStatus.OK);
}

下面通过调用这个方法,创建两个文档,具体内容如下:
在这里插入图片描述

4.3.2 批量创建文档

在一个 REST 请求中,重新建立网络开销是十分损耗性能的,因此 ES 提供 Bulk API,支持在一次 API 调用中,对不同的索引进行操作,从而减少网络传输开销,提升写入速率。

下面方法是批量创建文档,一个 BulkRequest 里可以添加多个 Request,具体代码如下:

public Boolean bulkCreateUserDocument(List<UserDocument> documents) throws IOException {BulkRequest bulkRequest = new BulkRequest();for (UserDocument document : documents) {String id = UUID.randomUUID().toString();document.setId(id);IndexRequest indexRequest = new IndexRequest(Constant.INDEX).id(id).source(JSON.toJSONString(document), XContentType.JSON);bulkRequest.add(indexRequest);}BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);return bulkResponse.status().equals(RestStatus.OK);
}

下面通过该方法创建些文档,便于下面的搜索演示。

4.3.3 查看文档

查看文档需要在 GetRequest 中传入索引名称和文档 id,具体代码如下所示:

public UserDocument getUserDocument(String id) throws IOException {GetRequest getRequest = new GetRequest(Constant.INDEX, id);GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);UserDocument result = new UserDocument();if (getResponse.isExists()) {String sourceAsString = getResponse.getSourceAsString();result = JSON.parseObject(sourceAsString, UserDocument.class);} else {logger.error("没有找到该 id 的文档");}return result;
}

下面传入文档 id 调用该方法,结果如下所示:
在这里插入图片描述

4.3.4 更新文档

更新文档则是先给 UpdateRequest 传入索引名称和文档 id,然后通过传入新的 doc 来进行更新,具体代码如下:

public Boolean updateUserDocument(UserDocument document) throws Exception {UserDocument resultDocument = getUserDocument(document.getId());UpdateRequest updateRequest = new UpdateRequest(Constant.INDEX, resultDocument.getId());updateRequest.doc(JSON.toJSONString(document), XContentType.JSON);UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);return updateResponse.status().equals(RestStatus.OK);
}

下面将文档 id 为 9b8d9897-3352-4ef3-9636-afc6fce43b20 的文档的城市信息改为 handan,调用方法结果如下:
在这里插入图片描述

4.3.5 删除文档

删除文档只需要在 DeleteRequest 中传入索引名称和文档 id,然后执行 delete 方法就可以完成文档的删除,具体代码如下:

public String deleteUserDocument(String id) throws Exception {DeleteRequest deleteRequest = new DeleteRequest(Constant.INDEX, id);DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);return response.getResult().name();
}

介绍完文档的基本操作,接下来对搜索进行简单介绍:

4.4 搜索操作

简单的搜索操作需要在 SearchRequest 中设置将要搜索的索引名称(可以设置多个索引名称),然后通过 SearchSourceBuilder 构造搜索源,下面将 TermQueryBuilder 搜索查询传给 searchSourceBuilder,最后将 searchRequest 的搜索源设置为 searchSourceBuilder,执行 search 方法实现通过城市进行搜索,具体代码如下所示:

public List<UserDocument> searchUserByCity(String city) throws Exception {SearchRequest searchRequest = new SearchRequest();searchRequest.indices(Constant.INDEX);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", city);searchSourceBuilder.query(termQueryBuilder);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);return getSearchResult(searchResponse);
}

在这里插入图片描述

4.4.1 聚合搜索

聚合搜索就是给 searchSourceBuilder 添加聚合搜索,下面方法是通过 TermsAggregationBuilder 构造一个先通过城市就行分类聚合,其中还包括一个子聚合,是对年龄求平均值,然后在获取聚合结果的时候,可以使用通过在构建聚合时的聚合名称获取到聚合结果,具体代码如下所示:

public List<UserCityDTO> aggregationsSearchUser() throws Exception {SearchRequest searchRequest = new SearchRequest(Constant.INDEX);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_city").field("city").subAggregation(AggregationBuilders.avg("average_age").field("age"));searchSourceBuilder.aggregation(aggregation);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);Aggregations aggregations = searchResponse.getAggregations();Terms byCityAggregation = aggregations.get("by_city");List<UserCityDTO> userCityList = new ArrayList<>();for (Terms.Bucket buck : byCityAggregation.getBuckets()) {UserCityDTO userCityDTO = new UserCityDTO();userCityDTO.setCity(buck.getKeyAsString());userCityDTO.setCount(buck.getDocCount());// 获取子聚合Avg averageBalance = buck.getAggregations().get("average_age");userCityDTO.setAvgAge(averageBalance.getValue());userCityList.add(userCityDTO);}return userCityList;
}

下面是执行该方法的结果:
在这里插入图片描述
到此为止,ES 的基本操作就简单介绍完了,大家可以多动手试试,不会的可以看下官方文档。

5 总结

本文的完整代码在https://github.com/363153421/springboot-elasticsearch下。

Spring Boot 结合 ES 还是比较简单的,大家可以下载项目源码,自己在本地运行调试这个项目,更好地理解如何在 Spring Boot 中构建基于 ES 的应用。

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

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

相关文章

巨好用又实用的18款3dMax插件!

3dMax是一款功能强大的 3D 软件&#xff0c;具有建模、动画、粒子动力学等许多强大功能。但并不是每个人都能有效地利用max的每一个功能&#xff0c;例如&#xff0c;很多人发现3dmax粒子流太难使用&#xff0c;3ds max蒙皮工具也是如此。 这让我们一些专业的开发公司或个人和…

前端如何结合mock模拟假数据

由于某人不想写后端接口&#xff0c;不想用真数据对接vue-element-admin框架&#xff0c;用以前的接口&#xff0c;改token有点点麻烦&#xff0c;所以咱试试mock.js

计算机网络期末复习-Part3

1、rdt1.0&#xff0c;rdt2.0&#xff0c;rdt3.0的底层信道模型 RDT 1.0: 完全可靠的底层信道&#xff0c;没有比特差错&#xff0c;也没有分组丢失。 RDT 2.0: 具有比特差错的底层信道&#xff0c;有比特差错&#xff0c;但没有分组丢失。 RDT 3.0: 具有差错和丢包的底层信道…

安哥拉市场开发攻略,收藏一篇就够了

安哥拉是非洲南部的一个国家&#xff0c;中国是安哥拉最大的贸易伙伴&#xff0c;安哥拉是中国在非洲的第二大贸易伙伴&#xff0c;中国人在安哥拉也是非常受欢迎的&#xff0c;虽然安哥拉经济比较落后&#xff0c;但是市场潜力还是非常不错的。今天就来给大家分享一下安哥拉的…

【开源分享】国内可用的免费安卓GPT语音助手 - 可音量键唤起,可联网

写在前面&#xff1a;这是一个我写的开源GPT语音助手&#xff0c;不收钱&#xff0c;只求Star! 简要介绍 这是一个基于ChatGPT的安卓端语音助手&#xff0c;允许用户通过手机音量键从任意界面唤起并直接进行语音交流&#xff0c;用最快捷的方式询问并获取回复 使用效果 一、基…

(动手学习深度学习)第13章 计算机视觉---图像增广与微调

13.1 图像增广 总结 数据增广通过变形数据来获取多样性从而使得模型泛化性能更好常见图片增广包裹翻转、切割、变色。 图像增广代码实现

Redis实现分布式锁

文章目录 前言一、概述为什么使用分布式锁基本原理分布式锁应该具备哪些条件常见的三种分布式锁 二、基于Redis实现分布式锁误删锁问题原子性问题最终代码实现 总结 前言 Redis实现简单分布式锁。 一、概述 为什么使用分布式锁 在多线程环境中&#xff0c;如果多个线程同时访…

确定性 vs 非确定性:GPT 时代的新编程范式

分享嘉宾 | 王咏刚 责编 | 梦依丹 出品 | 《新程序员》编辑部 在 ChatGPT 所引爆的新一轮编程革命中&#xff0c;自然语言取代编程语言&#xff0c;在只需编写提示词/拍照就能出程序的时代&#xff0c;未来程序员真的会被简化为提示词的编写员吗&#xff1f;通过提示词操纵 …

10-Docker-分布式存储算法

01-哈希取余算法分区 哈希取余分区&#xff08;Hash Modulus Partitioning&#xff09;是一种在分布式计算和数据存储中常用的分区策略&#xff0c;其目的是将数据或计算任务分配到多个节点或服务器上&#xff0c;以实现负载均衡和提高性能。这种分区策略的核心思想是使用哈希…

HCIA-hybrid经典小实验

hybrid经典小实验 实验拓扑配置实现SW1SW2 配置验证PC1-PC3 不能通信PC1-PC2 正常通信其他自行测试 实验拓扑 配置实现 SW1 sysname SW1 # undo info-center enable # vlan batch 10 20 30 # interface Ethernet0/0/1 //接口发送该vlan-id的数据帧时&#xff0c;不剥离帧中的…

多级缓存之实现多级缓存

多级缓存的实现离不开Nginx编程&#xff0c;而Nginx编程又离不开OpenResty。 1. OpenResty快速入门 我们希望达到的多级缓存架构如图&#xff1a; 其中&#xff1a; windows上的nginx用来做反向代理服务&#xff0c;将前端的查询商品的ajax请求代理到OpenResty集群 OpenRest…

容器网络-Underlay和Overlay

一、主机网络 前面讲了容器内部网络&#xff0c;但是容器最终是要部署在主机上&#xff0c;跨主机间的网络访问又是怎么样的&#xff0c;跨主机网络主要有两种方案。 二、 Underlay 使用现有底层网络&#xff0c;为每一个容器配置可路由的网络IP。也就是说容器网络和主机网络…

三掌柜第2期赠书活动:《计算机考研精炼1000题》

引言 各位朋友大家好&#xff0c;我是三掌柜。今天&#xff0c;三掌柜赠书第2期启动&#xff0c;本次为大家精选了《计算机考研精炼1000题》这本书。关于这本书的内容&#xff0c;非常丰富&#xff0c;涵盖计算机考研的高频知识内容&#xff0c;不管是正在备考&#xff0c;还是…

Python Opencv实践 - 车牌定位(纯练手,存在失败场景,可以继续优化)

使用传统的计算机视觉方法定位图像中的车牌&#xff0c;参考了部分网上的文章&#xff0c;实际定位效果对于我目前使用的网上的图片来说还可以。实测发现对于车身本身是蓝色、或是车牌本身上方有明显边缘的情况这类图片定位效果较差。纯练手项目&#xff0c;仅供参考。代码中im…

科研检测机构服务预约小程序的效果如何

科研检测机构涵盖的业务比较广&#xff0c;比如水质检测、农产品检测、食品检测等&#xff0c;对相关从业者来说&#xff0c;可能需要频繁使用这些业务&#xff0c;或者个人偶尔需要一些东西检测。 对用户和检测机构来说&#xff0c;由于行业的特殊性&#xff0c;在实际发展中…

keepalived+Nginx+邮件

实验场景&#xff1a; 我使用keepalived保证nginx的高可用&#xff0c;我想知道什么时候ip发生漂移&#xff0c;可以让ip发生漂移的时候 我的邮箱收到消息. 如果对keepalived不了解&#xff0c;这有详细解释&#xff1a;keepalived与nginx与MySQL-CSDN博客https://blog.csdn.ne…

竞赛 行人重识别(person reid) - 机器视觉 深度学习 opencv python

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习行人重识别(person reid)系统 该项目…

【Copilot】登录报错 Extension activation failed: “No auth flow succeeded.“(VSCode)

问题描述 Visual Studio Code 登录 GitHub Copilot 插件报错。 在浏览器中成功授权 GitHub 账户&#xff0c;返回 VSCode 后仍然报错。 [ERROR] [default] [2023-11-06T12:34:56.185Z] Extension activation failed: "No auth flow succeeded."原因分析 网络环境问…

山西电力市场日前价格预测【2023-11-12】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-12&#xff09;山西电力市场全天平均日前电价为224.59元/MWh。其中&#xff0c;最高日前电价为434.30元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache&#xff08;JSR-107&#xff09;注解简化我们的开发。&#xfeff; 其…