拾忆Elasticsearch03:SpringBoot整合 Elasticsearch
1、 查看文档
1.1 elasticsearch官方文档
我们进入elasticsearch的官方文档,可以看到一个与客户端相关的东西
进入,可以看到有很多客户端,我们这里使用Java restful风格的客户端。
发现7.17版本里面只有一个高级客户端
查看一个低级版本,里面还有一个低级版本
可以看到低级客户端里面东西很少
我们这里使用高级客户端,至于新版本里面为什么抛弃低级客户端,不去探究。展开高级客户端,发现里面有个getting start和一大堆API
展开getting start
查看maven依赖,找到了原生的依赖。
高级Java REST客户端依赖于以下构件及其传递依赖项:
初始化阶段,我们创建RestHighLevelClient
实例需要一个REST低级客户端构建器;如果是集群,可以构建多个HttpHost
实例,使用完毕,调用close()
关闭,释放资源。
更多的内容,感兴趣可以自行查看。
1.2 Spring Data ElasticSearch
Spring Data for Elasticsearch is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for for new datastores while retaining store-specific features and capabilities. The Spring Data Elasticsearch project provides integration with the Elasticsearch search engine.
Spring Data ElasticSearch是Spring对原生JAVA操作Elasticsearch封装之后的产物。它通过对原生API的封装,使得JAVA程序员可以简单的对Elasticsearch进行操作。
2、SpringBoot环境搭建
2.1 创建项目
我们先创建一个空的maven项目
然后在这个空项目下创建子模块
勾上你想要的
2.2 环境配置
2.3 导入依赖
创建模块时,我们勾选了NoSQL的starter data elasticsearch,自动给我们导入了依赖。
我们进入spring-boot-starter-data-elasticsearch
进入spring-data-elasticsearch
,在这里,我们看到了它导入了elasticsearch的高级客户端依赖,也就是我们前面说的原生依赖
打开 maven导入的依赖目录,可以看到spring-data-elasticsearch 2.7.2
导入的7.17.4
的client
。
注意,我们前面(就是上一篇)使用的elasticsearch
是7.6.2
,这里我们把它改成7.6.2
,保持版本一致。在pom中改成自己想要的版本即可。但修改elasticsearch版本,像我上面2.7.2
的Springboot改不了7.6.2
的elasticsearch。
查看elasticsearch、springboot、Spring data三者版本对应
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements
修改springboot和elasticsearch的版本。
修改成功。
我们在这里提前导入fastjson,后续需要。
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.41</version>
</dependency>
完整pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.goodwin</groupId><artifactId>es-api</artifactId><version>0.0.1-SNAPSHOT</version><name>es-api</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.3.7.RELEASE</spring-boot.version><elasticsearch.version>7.6.2</elasticsearch.version></properties><dependencies><!--导入了elasticsearch--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><!--导入fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.41</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>com.goodwin.EsApiApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
</project>
3、 相关API操作
3.1 创建并编写配置类
RestHighLevelClient
在第一节初始化已经见过,我们后续api
操作中需要用RestHighLevelClient
实例,我们将RestHighLevelClient
注入到Spring容器中
package com.goodwin.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;/*** @author goodwin*/
@Configuration
public class EsConfig {@Beanpublic RestHighLevelClient restHighLevelClient(){RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));return client;}
}
@Autowired@Qualifier("restHighLevelClient")RestHighLevelClient restHighLevelClient;
3.2 索引API操作
3.2.1 创建索引
RestHighLevelClient.indices()
提供一个用于访问Indices
API的IndicesClient
。
public final IndicesClient indices() {return indicesClient;
}
使用IndicesClient
实例,通过下图API可以看到,可以用于创建、删除索引等。
使用IndicesClient
的create
API创建索引。
public CreateIndexResponse create(CreateIndexRequest createIndexRequest,RequestOptions options) throws IOException {return restHighLevelClient.performRequestAndParseEntity(createIndexRequest, IndicesRequestConverters::createIndex, options,CreateIndexResponse::fromXContent, emptySet());
}
所以创建索引还需要createIndexRequest
和RequestOptions
实例。
在这里创建一个people
索引。
@Testvoid testCreateIndex() throws IOException {CreateIndexRequest indexRequest = new CreateIndexRequest("people");CreateIndexResponse createIndexResponse =restHighLevelClient.indices().create(indexRequest, RequestOptions.DEFAULT);System.out.println(createIndexResponse.isAcknowledged()); // 查看是否创建成功System.out.println(createIndexResponse); // 查看返回对象restHighLevelClient.close();}
输出
true
org.elasticsearch.client.indices.CreateIndexResponse@c4f5c12e
3.2.2 判断索引是否存在
根据创建索引的套路,这里直接给出判断索引是否存在的示例,有兴趣的可以自行阅读源码。
@Testvoid testIndexIsExists() throws IOException {boolean exists = restHighLevelClient.indices().exists(new GetIndexRequest("people"),RequestOptions.DEFAULT);System.out.println(exists);restHighLevelClient.close();}
输出
true
3.2.3 为索引添加结构
@Testvoid testSetIndex() throws IOException {// 创建请求对象PutMappingRequest request = new PutMappingRequest("people");request.setTimeout(new TimeValue(20, TimeUnit.SECONDS));// 设置mappingString mappingSource = "{ " +" \"properties\":{ " +" \"id\":{ " +" \"type\":\"integer\", " +" \"store\":true, " +" \"index\":true" +" }," +" \"name\":{ " +" \"type\":\"text\", " +" \"store\":true, " +" \"index\":true," +" \"analyzer\":\"ik_smart\"" +" " +" }," +" \"description\":{" +" \"type\":\"text\", " +" \"store\":true, " +" \"index\":true," +" \"analyzer\":\"ik_smart\"" +" }," +" \"hobby\":{" +" \"type\":\"text\", " +" \"store\":true, " +" \"index\":true," +" \"analyzer\":\"ik_smart\"," +" \"fields\" : {" +" \"keyword\" : {" +" \"type\" : \"text\"" +" }" +" }" +" }" +" }" +"}";request.source( mappingSource, XContentType.JSON);// 发送请求AcknowledgedResponse response = restHighLevelClient.indices().putMapping(request,RequestOptions.DEFAULT);// 输出返回结果System.out.println(response.isAcknowledged());// 关闭客户端restHighLevelClient.close();}
对应这个
输出
true
3.2.4 删除索引
@Testvoid testDeleteIndex() throws IOException {AcknowledgedResponse response = restHighLevelClient.indices().delete(new DeleteIndexRequest("people"), RequestOptions.DEFAULT);System.out.println(response.isAcknowledged());restHighLevelClient.close();}
输出
true
3.3 文档API操作
3.3.1 创建一个实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class People {private int id;private String name;private String description;private List<String> hobby;
}
3.3.2 文档的新增
下面java
代码相当于
PUT /people/_doc/1
{"id":1001,"name":"邓紫棋","description":"一位创作型歌手,一个天才美女。","hobby":["唱歌","创作"]
}
@Testvoid testAddDocument() throws IOException {// 创建一个People实例People people = new People(1001,"邓紫棋","一位创作型歌手,一个天才美女。",Arrays.asList("唱歌", "创作"));//实例对应的json字符串String jsonString = JSON.toJSONString(people);//创建请求IndexRequest request = new IndexRequest("people");//制定规则 PUT /people/_doc/1//设置idrequest.id("1");//设置超时request.timeout("1s");//设置数据源和内容类型request.source(jsonString,XContentType.JSON);//客户端发送请求,获取响应的结果IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);//获取建立索引的状态信息System.out.println(response.status());//查看返回内容System.out.println(response.toString());restHighLevelClient.close();}
输出
CREATED
IndexResponse[index=people,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
3.3.3 查看文档是否存在
@Testvoid testIsExistDocument() throws IOException {GetRequest request = new GetRequest("people", "1");//不获取返回的 _source的上下文了FetchSourceContext fetchSourceContext = new FetchSourceContext(false);//允许设置这个请求的FetchSourceContext,控制是否以及如何返回_source。request.fetchSourceContext(fetchSourceContext);//显式指定将返回的存储字段。默认情况下,将返回_source字段。request.storedFields("_none_");boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);System.out.println(exists);restHighLevelClient.close();}
true
3.3.4 文档的修改
@Testvoid testUpdateDocument() throws IOException {UpdateRequest updateRequest = new UpdateRequest("people","1");People people = new People();people.setId(1002);updateRequest.doc(JSON.toJSONString(people), XContentType.JSON);UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);System.out.println(update.status());restHighLevelClient.close();}
OK
以上相当于,不修改的部分不会丢失。
POST /people/_doc/1/_update
{"doc":{"id":1002}
}
3.3.5 文档的删除
@Testvoid testDeleteDocument() throws IOException {DeleteRequest request = new DeleteRequest("people","1");request.timeout("1s");DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);System.out.println(response.status());restHighLevelClient.close();}
OK
3.3.6 文档的批量操作
前面文档的新增,使用IndexRequest
实例的source
方法设置数据源和内容类型,查看源码可以发现在IndexRequest
重载了很多source
方法。
但它们最终都走向调用
public IndexRequest source(BytesReference source, XContentType xContentType) {this.source = Objects.requireNonNull(source);this.contentType = Objects.requireNonNull(xContentType);return this;}
可以看到,如果我们企图多次调用source
方法来批量添加数据,是不可行的,this.source
和this.contentType
只会指向最后一次设置的数据。修改亦是如此。
查看RestHighLevelClient
源码,发现可以使用bulk
API执行批量请求。
上述两个方法都需要我们传入一个BulkRequest
对象,在这个类中,重载了很多add
方法,它们的参数是XXXRequest
,很明显,我们只要批量add
上各种Request
就可以进行批量操作。
下面进行批量添加
@Testvoid testBulkAddDocument() throws IOException {BulkRequest bulkRequest = new BulkRequest("people");ArrayList<People> list = new ArrayList<>();list.add(new People(1001,"邓紫棋","一位创作型歌手,一个天才美女。",Arrays.asList("唱歌", "创作")));list.add(new People(1002,"蔡徐坤","一个穿背带裤的两年半练习生,是一个人气艺人。",Arrays.asList("唱","跳","rap","篮球")));list.add(new People(1003,"小黑子","自诩是ikun,是一类自称是蔡徐坤粉丝的群体,包括俊男美女。",Arrays.asList("香精煎鱼","香翅捞饭","油饼","荔枝","美食","卤醋鸡脚")));list.add(new People(1004,"Gloria","邓紫棋在新专辑《启示录》MV中的虚拟人物,同时也是邓紫棋爸爸给她取得英文名字。",Collections.singletonList("未知")));for (People people : list) {bulkRequest.add(new IndexRequest("people") //加入一个Request.id(Integer.toString(people.getId())) //没有设置id 会自定生成一个随机id.source(JSON.toJSONString(people),XContentType.JSON)//设置数据);}BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.status());restHighLevelClient.close();}
OK
3.3.7 文档的搜索
SearchSourceBuilder
是一个搜索源构建器,允许轻松构建搜索源,用来设置各种搜索条件。使用SearchRequest
中的source(SearchSourceBuilder sourceBuilder)
设置搜索请求的源。
SearchSourceBuilder
中的一些API
:
SearchSourceBuilder.query(QueryBuilder query)
为此请求设置搜索构建器,QueryBuilder
有非常多的实现类XXXQueryBuilder
。
这里我们能看到很多在上一篇讲过的,例如bool
多条件查询、match
模糊匹配、term/terms
精确查询等有关的构建器。SearchSourceBuilder.highlighter(HighlightBuilder highlightBuilder)
指定高亮构建器SearchSourceBuilder.fetchSource(···)
指示响应是否应该包含每个命中的存储的_source
SearchSourceBuilder.sort(SortBuilder<?> sort)
:设置排序
更多方法自行阅读源码。
@Testvoid testSearchDocument() throws IOException {//创建搜索源构建器SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//多条件查询构建器BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();//创建两个模糊匹配构建器MatchQueryBuilder matchQueryBuilder1 = new MatchQueryBuilder("name","邓紫棋");MatchQueryBuilder matchQueryBuilder2 = new MatchQueryBuilder("description","邓紫棋");//将两个MatchQueryBuilder实例丢到boolQueryBuilder中boolQueryBuilder.should(matchQueryBuilder1);boolQueryBuilder.should(matchQueryBuilder2);//设置搜索源构建器的搜索构建器searchSourceBuilder.query(boolQueryBuilder);//设置高亮HighlightBuilder highlightBuilder = new HighlightBuilder();//添加字段以高亮显示highlightBuilder.field("name");highlightBuilder.field("description");//设置用于高亮显示的开头和结尾标记。highlightBuilder.preTags("<em>");highlightBuilder.postTags("</em>");//设置搜索源构建器的高亮构建器searchSourceBuilder.highlighter(highlightBuilder);//设置超时searchSourceBuilder.timeout(new TimeValue(2,TimeUnit.SECONDS));SearchRequest request = new SearchRequest("people");request.source(searchSourceBuilder);SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);//打印执行状态System.out.println(response.status());//获得结果SearchHits hits = response.getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsMap());//获取高亮Map<String, HighlightField> highlightFields = hit.getHighlightFields();//输出高亮for (Map.Entry<String, HighlightField> stringHighlightFieldEntry : highlightFields.entrySet()) {System.out.println(stringHighlightFieldEntry);}}restHighLevelClient.close();}
OK
{name=Gloria, description=邓紫棋在新专辑《启示录》MV中的虚拟人物,同时也是邓紫棋爸爸给她取得英文名字。, id=1004, hobby=[未知]}
description=[description], fragments[[<em>邓紫棋</em>在新专辑《启示录》MV中的虚拟人物,同时也是<em>邓紫棋</em>爸爸给她取得英文名字。]]
{name=邓紫棋, description=一位创作型歌手,一个天才美女。, id=1001, hobby=[唱歌, 创作]}
name=[name], fragments[[<em>邓紫棋</em>]]
以上相当于在kibana执行以下语句
GET /people/_search
{"query": {"bool": {"should": [{"match": {"name": "邓紫棋"}},{"match": {"description": "邓紫棋"}}]}},"highlight": {"pre_tags": "<em>","post_tags": "</em>","fields": {"description": {},"name":{}}}
}
更多复杂搜索请各位自行探究,(¦3[▓▓] 晚安。
拾忆Elasticsearch03:SpringBoot整合 Elasticsearch相关推荐
- es springboot 不设置id_原创 | 一篇解决Springboot 整合 Elasticsearch
ElasticSearch 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务. ElasticSearch是一个基于Lucene的 ...
- 七、SpringBoot整合elasticsearch集群
@Author : By Runsen @Date : 2020/6/12 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘 ...
- SpringBoot整合ElasticSearch实现多版本的兼容
前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...
- SpringBoot整合elasticsearch (java整合es)
欢迎大家进群,一起探讨学习 微信公众号,每天给大家提供技术干货 博主技术笔记 博主网站地址1 博主网站地址2 博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star SpringBoot整合 ...
- SpringBoot 整合ElasticSearch全文检索
ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java语言开发的,并作为Apa ...
- Springboot整合Elasticsearch(High-level-Client)
前言 通过学习Elasticsearch一小段时间来稍微认识了一点ES的体系架构.发现ES最大的坑就是版本兼容性问题了-在整合Springboot也不例外,但是,有一种方式能较好的解决-通过restc ...
- Elasticsearch的安装,以及Springboot整合Elasticsearch
*一.下载好elasticsearch并解压 我这里用的是elasticsearch-5.6.8,下面是下载地址 https://artifacts.elastic.co/downloads/elas ...
- SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)
准备工作# 环境准备# JAVA版本 Copy java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1. ...
- 【十九】springboot整合ElasticSearch实战(万字篇)
本章开始学习springboot整合ElasticSearch 7.X版本并通过小demo实现基本的增删改查.实现如下案例: 1.当向数据新增一个商品信息时,同时向rabbitMQ发起消息(异步实现) ...
- Springboot 整合ElasticSearch 常用的插入查询,模糊查询,范围查询
前言 本来该篇教程就应该写到 Springboot 整合 ElasticSearch 入门教学必看 https://blog.csdn.net/qq_35387940/article/details/ ...
最新文章
- 如何监听Canvas上滚动条的出现或隐藏
- 第一章 GuassDB数据库介绍
- kylin3.x安装,解决load hive表的时候提示shaded-guava问题
- 7 useLayoutEffect、useDebugValue
- 内部设计师揭秘!王者峡谷中竟有隐藏的c++代码??!!腾讯已经炸了!!!
- json符号解释大全_牛年汪姓男孩高端大气的名字大全
- 神秘的安全测试思考案例(一)
- .net文件请求iis的回话的工作原理
- 计算机不能代替人类英语作文,2013年雅思写作范文:电脑翻译能取代人吗?
- 有谁还记得“开源”已经20年了!
- Bailian3751 地质考察队【最值】
- 友盟分享长图片,如何截取长图片去分享
- Windows10系统提示 为了对电脑进行保护,已经阻止此应用(管理员已阻止你运行此应用。有关详细信息,请与管理员联系。)的解决办法
- javajavaScript常见校验器
- u盘,tf卡,MP3,500次就报废了!
- Photoshop给图片替换蓝天白云背景
- C++简单程序典型案例
- 色散共焦传感器如何进行同步信号输出?
- Java有关于面向对象中的【抽象类、抽象方法和多态】的解释(初学者)
- 勇往直前的菜鸟修炼手册
热门文章
- java简单实现仿QQ登陆界面
- 关于mysql中无法显示中文的完美解决方案
- php 微信 ca证书出错,升级CA颁发的证书后微信退款、红包等无法使用
- 51单片机入门(2)LED点亮的背后
- Arduino与Proteus仿真实例-密码门禁控制仿真
- u盘恢复数据|U盘打不开提示格式化怎么恢复数据?
- 测试人遇到被测 APP 要下架,怎么处理?
- 科研热点|2022诺贝尔奖各领域奖项已揭晓(附获奖者详细信息)~
- UIQ3.0系列--在模拟器上显示中文
- 2018年全国多校算法寒假训练营练习比赛(第五场)F-The Biggest Water Problem