ES7学习笔记(十一)与SpringBoot结合
在前面的章节中,我们把ES的基本功能都给大家介绍完了,从ES的搭建、创建索引、分词器、到数据的查询,大家发现,我们都是通过ES的API去进行调用,那么,我们在项目当中怎么去使用ES呢?这一节,我们就看看ES如何与我们的SpringBoot项目结合。
版本依赖
SpringBoot默认是有ElasticSearch的Starter,但是它依赖的ES客户端的版本比较低,跟不上ES的更新速度,所以我们在SpringBoot项目中要指定ES的最新版本,如下:
<properties> <elasticsearch.version>7.6.1</elasticsearch.version> </properties> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
我们在项目中指定ES客户端的版本为7.6.1。
配置文件
然后我们在SpringBoot的配置文件application.properties
当中,配置ES集群的地址,如下:
spring.elasticsearch.rest.uris=http://192.168.73.130:9200,http://192.168.73.131:9200,http://192.168.73.132:9200
多个地址之间我们使用,
隔开即可。
与ES交互
所有配置的东西都准备好了,下面我们看看在程序当中如何交互,还记得前面咱们提到的动态映射吗?这个东西是非常的好用的,简化了我们不少的工作量。在这里我们还用前面的索引ik_index
举例,我们先看看目前ik_index
索引中有哪些字段,
在索引中只有3个字段,id、title和desc。接下来我们在创建索引ik_index
对应的实体类,内容也很简单,具体如下:
@Setter@Getter public class IkIndex { private Long id; private String title; private String desc; private String category; }
在实体类中,我们新添加了一个字段category
表示分类,我们可以联想一下,category
字段动态映射到ES当中会是什么类型?对了,就是text
类型,我们再深入想一步,text
类型会用到全文索引,会用到分词器,而在索引ik_index
当中,我们配置了默认的分词器是IK中文分词器。能够想到这里,我觉得你对ES了解的比较深入了。
接下来,我们就要编写service
了,并向ik_index
索引中添加一条新的数据,如下:
@Service public class EService { @Autowired private RestHighLevelClient client; /** * 添加索引数据 * @throws IOException */ public void insertIkIndex() throws IOException { IkIndex ikIndex = new IkIndex(); ikIndex.setId(10l); ikIndex.setTitle("足球"); ikIndex.setDesc("足球是世界第一运动"); ikIndex.setCategory("体育"); IndexRequest request = new IndexRequest("ik_index"); // request.id("1"); request.source(JSON.toJSONString(ikIndex), XContentType.JSON); IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT); System.out.println(indexResponse.status()); System.out.println(indexResponse.toString()); } }
首先,我们要引入ES的高等级的客户端RestHighLevelClient
,由于我们在配置文件中配置了ES集群的地址,所以SpringBoot自动为我们创建了RestHighLevelClient
的实例,我们直接自动注入就可以了。然后在添加索引数据的方法中,我们先把索引对应的实体创建好,并设置对应的值。
接下来我们就要构建索引的请求了,在IndexRequest
的构造函数中,我们指定了索引的名称ik_index
,索引的id被我们注释掉了,ES会给我们默认生成id,当然自己指定也可以。大家需要注意的是,这个id和IkIndex
类里的id不是一个id,这个id是数据在ES索引里的唯一标识,而IkIndex
实体类中的id只是一个数据而已,大家一定要区分开。然后我们使用request.source
方法将实体类转化为JSON对象并封装到request
当中,最后我们调用client
的index
方法完成数据的插入。我们看看执行结果吧。
CREATED IndexResponse[index=ik_index,type=_doc,id=f20EVHIBK8kOanEwfXbW,version=1,result=created,seqNo=9,primaryTerm=6,shards={"total":2,"successful":2,"failed":0}]
status
返回的值是CREATED
,说明数据添加成功,而后面的响应信息中,包含了很多具体的信息,像每个分片是否成功都已经返回了。我们再用elasticsearch-head
插件查询一下,结果如下:
数据插入成功,并且新添加的字段category
也有了对应的值,这是我们期望的结果。下面我们再看看查询怎么使用。代码如下:
public void searchIndex() throws IOException { SearchRequest searchRequest = new SearchRequest("ik_index"); SearchSourceBuilder ssb = new SearchSourceBuilder(); QueryBuilder qb = new MatchQueryBuilder("desc","香蕉好吃"); ssb.query(qb); searchRequest.source(ssb); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] hits = response.getHits().getHits(); for (SearchHit hit : hits) { String record = hit.getSourceAsString(); System.out.println(record); } }
- 我们先创建一个查询请求,并指定索引为
ik_index
; - 然后我们创建一个请求体
SearchSourceBuilder
,再构建我们的查询请求QueryBuilder
,QueryBuilder
是一个接口,它的实现类有很多,对应着ES中的不同种类的查询,比如咱们前面介绍的bool
和boosting
查询,都有对应的实现类。在这里,咱们使用MatchQueryBuilder
并查询desc
包含香蕉好吃
的数据,这个查询咱们在前面通过API的方式也查询过。 - 最后我们封装好请求,并通过
client.search
方法进行查询,返回的结构是SearchResponse
。 - 在返回的结果中,我们获取对应的数据,咦?这个为什么调用了两次Hits方法?咱们可以从API的返回值看出端倪,如下:
- 我们可以看到返回的结果中确实有两个hits,第一个hits中包含了数据的条数,第二个hits中才是我们想要的查询结果,所以在程序中,我们调用了两次hits。
- 在每一个hit当中,我们调用
getSourceAsString
方法,获取JSON格式的结果,我们可以用这个字符串通过JSON工具映射为实体。
我们看看程序运行的结果吧,
{"id":1,"title":"香蕉","desc":"香蕉真好吃"} {"id":1,"title":"香蕉","desc":"香蕉真好吃"} {"id":1,"title":"橘子","desc":"橘子真好吃"} {"id":1,"title":"桃子","desc":"桃子真好吃"} {"id":1,"title":"苹果","desc":"苹果真好吃"}
查询出了5条数据,和我们的预期是一样的,由于使用IK中文分词器,所以desc
中包含好吃
的都被查询了出来,而我们新添加的足球
数据并没有查询出来,这也是符合预期的。我们再来看看聚合查询怎么用,
public void searchAggregation() throws IOException { SearchRequest searchRequest = new SearchRequest("ik_index"); SearchSourceBuilder ssb = new SearchSourceBuilder(); TermsAggregationBuilder category = AggregationBuilders.terms("category").field("category.keyword"); ssb.aggregation(category); searchRequest.source(ssb); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); Terms terms = response.getAggregations().get("category"); for (Terms.Bucket bucket : terms.getBuckets()) { System.out.println(bucket.getKey()); System.out.println(bucket.getDocCount()); } }
- 同样,我们创建一个
SearchRequest
,然后再创建一个TermsAggregationBuilder
,TermsAggregationBuilder
我们指定了name
叫做category
,这个name
对应着上一节中的那个自定义的名称,大家还有印象吗? - 后面的
field
是我们要聚合的字段,注意这里因为category
字段是text
类型,默认是不能够做聚合查询的,我们指定的是category.keyword
,还记得这个keyword
类型吗?它是不使用分词器的,我们使用这个keyword
类型是可以的。 - 最后把
AggregationBuilder
封装到查询请求中,进行查询。 - 查询后,我们怎么去取这个
aggregation
呢?取查询结果我们是通过hits
,取聚合查询,我们要使用aggregation
了,然后再get我们的自定义名称response.getAggregations().get("category")
。至于前面的类型,它是和AggregationBuilder
对应的,在咱们的例子中使用的是TermsAggregationBuilder
,那么我们在取结果时就要用Terms
;如果查询时使用的是AvgAggregationBuilder
,取结果时就要用Avg
。 - 在取得
Terms
后,我们可以获取里边的值了。运行一下,看看结果。
体育 1
key
是体育,doc_count
是1,说明分类体育
的数据只有1条。完全符合我们的预期,这个聚合查询的功能非常重要,在电商平台中,商品搜索页通常列出所有的商品类目,并且每个类目后面都有这个商品的数量,这个功能就是基于聚合查询实现的。
好了,到这里,ES已经结合到我们的SpringBoot项目中了,并且最基础的功能也已经实现了,大家放心的使用吧~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
ES7学习笔记(九)搜索
搜索是ES最最核心的内容,没有之一。前面章节的内容,索引、动态映射、分词器等都是铺垫,最重要的就是最后点击搜索这一下。下面我们就看看点击搜索这一下的背后,都做了哪些事情。 分数(score) ES的搜索结果是按照相关分数的高低进行排序的,咦?! 怎么没说搜索先说搜索结果的排序了?咱们这里先把这个概念提出来,因为在搜索的过程中,会计算这个分数。这个分数代表了这条记录匹配搜索内容的相关程度。分数是一个浮点型的数字,对应的是搜索结果中的_score字段,分数越高代表匹配度越高,排序越靠前。 在ES的搜索当中,分为两种,一种计算分数,而另外一种是不计算分数的。 查询(query context) 查询,代表的是这条记录与搜索内容匹配的怎么样,除了决定这条记录是否匹配外,还要计算这条记录的相关分数。这个和咱们平时的查询是一样的,比如我们搜索一个关键词,分词以后匹配到相关的记录,这些相关的记录都是查询的结果,那这些结果谁排名靠前,谁排名靠后呢?这个就要看匹配的程度,也就是计算的分数。 过滤(filter context) 过滤,代表的含义非常的简单,就是YES or NO,这条记录是否匹配查询条件...
- 下一篇
Ali Elasticsearch内核最新小版本1.0.2发布
信息摘要: 阿里云Elasticsearch定期进行内核小版本优化,涉及性能提升、新功能或问题修复等,并支持用户手动升级内核小版本。适用客户: 阿里云Elasticsearch6.7版本用户版本/规格功能: 内核最新小版本特性: 支持查询access.log,包括请求时间、客户端来源、请求内容等,可用于问题排查和请求分析; 支持配置JVM熔断策略,JVM达到95%后会拒绝请求保护集群; 主节点调度性能提升10倍,支持调度更多分片数 https://developer.aliyun.com/article/745572?utm_content=g_1000115954。 写入性能提升10%,降低translog落盘锁的开销;https://segmentfault.com/a/1190000020375493产品文档: https://help.aliyun.com/document_detail/157362.html
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Mario游戏-低调大师作品