SpringBoot集成ElasticSearch
·
前言
被逼无奈,各行各业都在卷,给自己充电学习了Elasticsearch,在学完基础知识后(其实就是CRUD😂),就去Springboot中尝试整合ES。终于抽出时间,将学习的东西整理分享在此,欢迎大家批评指正哈~
一、ElasticSearch本地环境搭建
详细安装步骤参考此资料windows 安装 Elasticsearch
二、SpringBoot整合ElasticSearch
我这里Spring Boot版本2.7.5,ElasticSearch版本7.17.3。版本一定要对应上,否则会报一堆错误问题。
SpringBoot官方推荐对应Elasticsearch版本。
先启动ES本地服务(双击elasticsearch.bat启动服务),然后在elasticsearch-head可视化插件目录中执行npm start run
启动可视化插件。
1.pom中引入ES依赖
<!-- ElasticSearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<exclusions>
<exclusion>
<artifactId>elasticsearch-java</artifactId>
<groupId>co.elastic.clients</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.0.1</version>
<exclusions>
<exclusion>
<artifactId>jakarta.json-api</artifactId>
<groupId>jakarta.json</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.0.1</version>
</dependency>
2.application.yaml配置elasticsearch
elasticsearch:
port: 9200
ip: 127.0.0.1
username: elastic
password: 123456
3.ElasticSearchClientConnect连接ES客户端工具类
@Configuration
public class ElasticSearchClientConnect {
@Value("${elasticsearch.port}")
private int port;
@Value("${elasticsearch.ip}")
private String ip;
@Value("${elasticsearch.username}")
private String username;
@Value("${elasticsearch.password}")
private String password;
/**
* 创建rest客户端
*/
@Bean
public ElasticSearchResult restClient(){
RestClient restClient = RestClient.builder(
new HttpHost(ip, port,"http")).build();
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
return new ElasticSearchResult(restClient,transport,client);
}
}
4.ElasticSearchResult封装响应结果
@Data
public class ElasticSearchResult {
private RestClient restClient;
private ElasticsearchTransport elasticsearchTransport;
private ElasticsearchClient elasticsearchClient;
public ElasticSearchResult(RestClient restClient, ElasticsearchTransport elasticsearchTransport, ElasticsearchClient elasticsearchClient) {
this.restClient = restClient;
this.elasticsearchTransport = elasticsearchTransport;
this.elasticsearchClient = elasticsearchClient;
}
}
5.Person实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String sex;
private Integer age;
}
6.ElasticsearchController增删改查控制层
/**
* ES增删改查
*/
@RestController
public class ElasticsearchController {
@Autowired
private ElasticSearchClientConnect elasticSearchClientConfig;
/**
* 新建my_index索引
* @return
* @throws IOException
*/
@GetMapping("/createIndex")
public Boolean createIndex() throws IOException {
CreateIndexResponse createIndexResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().indices().create(c -> c.index("my_index"));
// 打印结果
System.out.println(createIndexResponse.acknowledged());
// 关闭连接
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
return createIndexResponse.acknowledged();
}
/**
* 查询索引
* @throws IOException
*/
@GetMapping("/selectIndex")
public void selectIndex() throws IOException {
GetIndexResponse getIndexResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().indices().get(e -> e.index("jing_index"));
// 打印结果
System.out.println("getIndexResponse.result() = " + getIndexResponse.result());
System.out.println("getIndexResponse.result().keySet() = " + getIndexResponse.result().keySet());
// 关闭连接
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 删除索引
* @return
* @throws IOException
*/
@GetMapping("/deleteIndex")
public Boolean deleteIndex() throws IOException {
// 删除索引
DeleteIndexResponse deleteIndexResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().indices().delete(e -> e.index("jing_index"));
System.out.println("删除操作 = " + deleteIndexResponse.acknowledged());
// 关闭连接
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
return deleteIndexResponse.acknowledged();
}
}
7.ElasticsearchDocumentController文档操作控制层
/**
* ES文档操作
*/
@RestController
public class ElasticsearchDocumentController {
@Autowired
private ElasticSearchClientConnect elasticSearchClientConfig;
/**
* 添加document
* @throws IOException
*/
@GetMapping("/addDocument")
public void addDocument() throws IOException {
// 向Person对象中添加数据
Person Person = new Person("java客户端", "男", 18);
// 向索引中添加数据
CreateResponse createResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().create(e -> e.index("jing_index").id("1001").document(Person));
System.out.println("createResponse.result() = " + createResponse.result());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 查询document
* @throws IOException
*/
@GetMapping("/queryDocument")
public void queryDocument() throws IOException {
// 构建请求
GetResponse<Person> getResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().get(e -> e.index("jing_index").id("1001"), Person.class);
System.out.println("getResponse.source().toString() = " + getResponse.source().toString());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 修改document
* @throws IOException
*/
@GetMapping("/modifyDocument")
public void modifyDocument() throws IOException {
// 使用map集合封装需要修改的内容
Map<String, Object> map = new HashMap<>();
map.put("name", "java客户端aaa");
// 构建请求
UpdateResponse<Person> updateResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().update(e -> e.index("jing_index").id("1001").doc(map), Person.class);
System.out.println("updateResponse.result() = " + updateResponse.result());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 删除document
* @throws IOException
*/
@GetMapping("/removeDocument")
public void removeDocument() throws IOException {
// 构建请求
DeleteResponse deleteResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().delete(e -> e.index("jing_index").id("1001"));
System.out.println("deleteResponse.result() = " + deleteResponse.result());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 批量添加document
* @throws IOException
*/
@GetMapping("/batchAddDocument")
public void batchAddDocument() throws IOException {
// 构建一个批量数据集合
List<BulkOperation> list = new ArrayList<>();
list.add(new BulkOperation.Builder().create(
d -> d.document(new Person("test2", "男", 19)).id("1002").index("Person_test")).build());
list.add(new BulkOperation.Builder().create(
d -> d.document(new Person("test3", "男", 20)).id("1003").index("Person_test")).build());
list.add(new BulkOperation.Builder().create(
d -> d.document(new Person("test4", "女", 21)).id("1004").index("Person_test")).build());
// 调用bulk方法执行批量插入操作
BulkResponse bulkResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().bulk(e -> e.index("Person_test").operations(list));
System.out.println("bulkResponse.items() = " + bulkResponse.items());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 批量删除document
* @throws IOException
*/
@GetMapping("/batchDeleteDocument")
public void batchDeleteDocument() throws IOException {
// 构建一个批量数据集合
List<BulkOperation> list = new ArrayList<>();
list.add(new BulkOperation.Builder().delete(
d -> d.id("1002").index("Person_test")).build());
list.add(new BulkOperation.Builder().delete(
d -> d.id("1003").index("Person_test")).build());
// 调用bulk方法执行批量插入操作
BulkResponse bulkResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().bulk(e -> e.index("Person_test").operations(list));
System.out.println("bulkResponse.items() = " + bulkResponse.items());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 全量查询document
* @throws IOException
*/
@GetMapping("/queryAllDocument")
public void queryAllDocument() throws IOException {
// 全量查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(e -> e.index("Person_test").query(q -> q.matchAll(m -> m)), Person.class);
HitsMetadata<Person> hits = searchResponse.hits();
for (Hit<Person> hit : hits.hits()) {
System.out.println("Person = " + hit.source().toString());
}
System.out.println("searchResponse.hits().total().value() = " + searchResponse.hits().total().value());
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 分页查询document
* @throws IOException
*/
@GetMapping("/pagingQueryDocument")
public void pagingQueryDocument() throws IOException {
// 分页查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(
s -> s.index("Person_test")
.query(q -> q.matchAll(m -> m))
.from(0)
.size(2)
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 排序查询document
* @throws IOException
*/
@GetMapping("/sortQueryDocument")
public void sortQueryDocument() throws IOException {
// 排序查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(
s -> s.index("Person_test")
.query(q -> q.matchAll(m -> m))
.sort(o -> o.field(f -> f.field("age").order(SortOrder.Asc)))
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 条件查询document
* @throws IOException
*/
@GetMapping("/conditionQueryDocument")
public void conditionQueryDocument() throws IOException {
// 条件查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(
s -> s.index("Person_test").query(q -> q.matchAll(m -> m))
.sort(o -> o.field(f -> f.field("age").order(SortOrder.Asc)))
.source(r -> r.filter(f -> f.includes("name", "age").excludes("")))
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 组合查询 must是必须满足所有条件,should只要满足一个就行
* @throws IOException
*/
@GetMapping("/combinationQueryDocument")
public void combinationQueryDocument() throws IOException {
// 组合查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(
s -> s.index("Person_test").query(q -> q.bool(b -> b
.must(m -> m.match(u -> u.field("age").query(21)))
.must(m -> m.match(u -> u.field("sex").query("男")))
.mustNot(m -> m.match(u -> u.field("sex").query("女")))
))
, Person.class);
//SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(
// s -> s.index("Person_test").query(q -> q.bool(b -> b
// .should(h -> h.match(u -> u.field("age").query(19)))
// .should(h -> h.match(u -> u.field("sex").query("男")))
// ))
// , Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 范围查询
* @throws IOException
*/
@GetMapping("/scopeQueryDocument2")
public void scopeQueryDocument2() throws IOException {
// 范围查询,gte()表示取大于等于,gt()表示大于,lte()表示小于等于
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(s -> s.index("Person_test").query(q -> q
.range(r -> r.field("age").gte(JsonData.of(20)).lt(JsonData.of(21))))
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 模糊查询
* @throws IOException
*/
@GetMapping("/fuzzyQueryDocument2")
public void fuzzyQueryDocument2() throws IOException {
// 模糊查询,fuzziness表示差几个可以查询出来
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(s -> s.index("Person_test").query(q -> q
.fuzzy(f -> f.field("name").value("tst").fuzziness("2")))
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 高亮查询
* @throws IOException
*/
@GetMapping("/highlightQueryDocument2")
public void highlightQueryDocument2() throws IOException {
// 高亮查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(s -> s.index("Person_test").query(q -> q
.term(t -> t.field("name").value("test4")))
.highlight(h -> h.fields("name", f -> f.preTags("<font color='red'>").postTags("</font>")))
, Person.class);
searchResponse.hits().hits().forEach(h -> System.out.println(h.source().toString()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 聚合查询
* @throws IOException
*/
@GetMapping("/aggregateQueryDocument2")
public void aggregateQueryDocument2() throws IOException {
// 聚合查询,取最大年龄
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(s -> s.index("Person_test").aggregations("maxAge", a ->a.max(m -> m.field("age")))
, Person.class);
searchResponse.aggregations().entrySet().forEach(f -> System.out.println(f.getKey() + ":" + f.getValue().max().value()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
/**
* 分组查询
* @throws IOException
*/
@GetMapping("/groupQueryDocument2")
public void groupQueryDocument2() throws IOException {
// 分组查询
SearchResponse<Person> searchResponse = elasticSearchClientConfig.restClient().getElasticsearchClient().search(s -> s.index("Person_test")
.aggregations("ageGroup", a ->a.terms(t -> t.field("age")))
, Person.class);
searchResponse.aggregations().get("ageGroup").lterms().buckets().array().forEach(f -> System.out.println(f.key() + ":" + f.docCount()));
elasticSearchClientConfig.restClient().getElasticsearchTransport().close();
elasticSearchClientConfig.restClient().getRestClient().close();
}
}
三、测试
1.创建索引,名为my_index
查询结果显示创建成功
2.创建文档,给名为my_index的索引创建文档
查询结果显示创建文档成功
四、项目结构及代码下载
源码下载地址,欢迎Star哦~~
springboot-cacheable
参考资料
SpringBoot官方推荐对应Elasticsearch版本
SpringBoot集成elasticsearch 7.17.3及常规应用
Elasticsearch8.x版本中RestHighLevelClient被弃用
SpringBoot 整合ElasticSearch实现模糊查询,批量CRUD,排序,分页,高亮
windows 安装 Elasticsearch
更多推荐
已为社区贡献8条内容
所有评论(0)