一、前言
Elasticsearch 是一个开源分布式搜索引擎,具有全文检索、数据分析等功能。在实际项目中,我们需要将 Elasticsearch 与 SpringBoot 进行整合,以实现数据的高效存储和快速检索。
本篇文章将介绍如何使用 SpringBoot 整合 Elasticsearch,并提供一些相关业务的示例代码。
二、环境准备
在进行 Elasticsearch 和 SpringBoot 的整合之前,需要先安装 Elasticsearch 和 SpringBoot。
1. Elasticsearch 的安装
可以从 Elasticsearch 的官网下载最新的稳定版,下载地址为:https://www.elastic.co/cn/downloads/elasticsearch
2. SpringBoot 的安装
SpringBoot 的安装可以通过官网进行下载,下载地址为:https://spring.io/projects/spring-boot
安装完成后,你可以使用以下命令验证 SpringBoot 是否安装成功:
$ java -version
$ mvn -v
三、SpringBoot 整合 Elasticsearch
1. 添加相关依赖
在 pom.xml 文件中添加 SpringBoot 和 Elasticsearch 的相关依赖,如下所示:
<!-- SpringBoot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.12.0</version>
</dependency>
2. Elasticsearch 的配置
在 application.yml 文件中添加 Elasticsearch 的配置信息,如下所示:
spring:
elasticsearch:
rest:
uris: http://localhost:9200
在这里,我们配置了 Elasticsearch 的主机地址和端口号。
3. 创建 Elasticsearch 的客户端
在 SpringBoot 中,我们可以使用 Elasticsearch 的 Java API 与 Elasticsearch 进行交互。下面是创建 Elasticsearch 客户端的实现代码:
@Configuration
public class ElasticsearchConfig {
private static final String ELASTICSEARCH_HOST = "localhost";
private static final int ELASTICSEARCH_PORT = 9200;
@Bean(destroyMethod = "close")
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost(ELASTICSEARCH_HOST, ELASTICSEARCH_PORT))
);
return restHighLevelClient;
}
}
在以上代码中,我们通过 RestHighLevelClient 类创建了 Elasticsearch 客户端,并将其定义为一个 Bean。
4. 创建 Elasticsearch 的映射和索引
在 Elasticsearch 中,映射用于描述数据的结构和特征,索引则用于将相关数据进行分类。下面是创建 Elasticsearch 的映射和索引的实现代码:
@Service
public class ElasticsearchService {
private static final String INDEX_NAME = "example-index";
private static final String MAPPING_NAME = "example-mapping";
private RestHighLevelClient restHighLevelClient;
public ElasticsearchService(RestHighLevelClient restHighLevelClient) {
this.restHighLevelClient = restHighLevelClient;
}
public void createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
}
public void createMapping() throws IOException {
PutMappingRequest request = new PutMappingRequest(INDEX_NAME);
request.source(getMappingBuilder());
restHighLevelClient.indices().putMapping(request, RequestOptions.DEFAULT);
}
private XContentBuilder getMappingBuilder() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("properties");
{
builder.startObject("id");
{
builder.field("type", "keyword");
}
builder.endObject();
builder.startObject("name");
{
builder.field("type", "text");
builder.field("analyzer", "ik_max_word");
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
return builder;
}
}
在以上代码中,我们通过 RestHighLevelClient 类创建了 Elasticsearch 客户端,并定义了 Elasticsearch 的映射和索引。将其定义为一个 Bean,并注入到 ElasticsearchService 类中,方便调用。
在 createIndex() 方法中,我们通过 CreateIndexRequest 类创建了一个新的索引,并使用 indices() 方法将其添加到 Elasticsearch 中。
在 createMapping() 方法中,我们使用 PutMappingRequest 类向 Elasticsearch 中添加映射,使用 getMappingBuilder() 方法创建了一个新的映射。
需要注意的是,在 getMappingBuilder() 方法中,我们使用了中文分词器 ik_max_word,可以使 Elasticsearch 对中文进行分词,提高搜索的准确性和效率。
5. 数据的增删改查
在 Elasticsearch 中,数据由文档组成,文档由字段构成。下面是一些常见的操作示例:
(1)添加文档
public void addDocument(Document document) throws IOException {
IndexRequest request = new IndexRequest(INDEX_NAME);
request.id(document.getId());
request.source(document.toJson(), XContentType.JSON);
restHighLevelClient.index(request, RequestOptions.DEFAULT);
}
在以上代码中,我们通过 IndexRequest 类创建了一个新的索引请求,并将文档添加到 Elasticsearch 中。
(2)删除文档
public void deleteDocument(String id) throws IOException {
DeleteRequest request = new DeleteRequest(INDEX_NAME, id);
restHighLevelClient.delete(request, RequestOptions.DEFAULT);
}
在以上代码中,我们通过 DeleteRequest 类创建了一个删除请求,并将指定的文档从 Elasticsearch 中删除。
(3)更新文档
public void updateDocument(Document document) throws IOException {
UpdateRequest request = new UpdateRequest(INDEX_NAME, document.getId());
request.doc(document.toJson(), XContentType.JSON);
restHighLevelClient.update(request, RequestOptions.DEFAULT);
}
在以上代码中,我们通过 UpdateRequest 类创建了一个更新请求,并使用 doc() 方法更新指定文档的字段。
(4)查询数据
public List<Document> searchDocuments(String keyword) throws IOException {
SearchRequest request = new SearchRequest(INDEX_NAME);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.matchQuery("name", keyword));
sourceBuilder.query(boolQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
List<Document> documents = new ArrayList<>();
for (SearchHit hit : hits) {
Document document = new Document();
document.setId(hit.getId());
document.setName((String) hit.getSourceAsMap().get("name"));
documents.add(document);
}
return documents;
}
在以上代码中,我们通过 SearchRequest 类创建了一个搜索请求,并使用 MatchQuery 实现对关键字的搜索。
同时,我们使用 SearchSourceBuilder 类设置了搜索请求的查询参数,并通过 restHighLevelClient.search() 方法获取了搜索结果。
最后,我们将搜索到的文档信息封装成一个 Document 类对象,并将其添加到 documents 列表中,返回给前端显示。
四、代码示例
下面是一个简单的使用 Elasticsearch 实现搜索功能的示例代码:
@RestController
@RequestMapping("/search")
public class HomeController {
@Autowired
private ElasticsearchService elasticsearchService;
@PostMapping("/create-index")
public String createIndex() {
try {
elasticsearchService.createIndex();
return "索引创建成功";
} catch (IOException e) {
return "索引创建失败";
}
}
@PostMapping("/create-mapping")
public String createMapping() {
try {
elasticsearchService.createMapping();
return "映射创建成功";
} catch (IOException e) {
return "映射创建失败";
}
}
@PostMapping("/add-document")
public String addDocument(@RequestBody Document document) {
try {
elasticsearchService.addDocument(document);
return "文档添加成功";
} catch (IOException e) {
return "文档添加失败";
}
}
@PostMapping("/update-document")
public String updateDocument(@RequestBody Document document) {
try {
elasticsearchService.updateDocument(document);
return "文档更新成功";
} catch (IOException e) {
return "文档更新失败";
}
}
@PostMapping("/delete-document")
public String deleteDocument(@RequestParam String id) {
try {
elasticsearchService.deleteDocument(id);
return "文档删除成功";
} catch (IOException e) {
return "文档删除失败";
}
}
@GetMapping("/search")
public List<Document> searchDocuments(@RequestParam String keyword) {
try {
return elasticsearchService.searchDocuments(keyword);
} catch (IOException e) {
return Collections.emptyList();
}
}
}
在以上代码中,我们创建了一个简单的前端控制器,对索引、映射、文档的添加、更新和删除进行了处理。同时,我们通过 GetMapping 实现对关键字的搜索,将搜索结果返回给前端。
五、总结
本文介绍了如何使用 SpringBoot 实现 Elasticsearch 的整合,并提供了数据的增删改查示例代码。通过本文的学习,相信你已经初步掌握了 Elasticsearch 的基本使用和 SpringBoot 与 Elasticsearch 的整合方式。
希望本文能对你有所帮助,如果有不足之处,欢迎指正,谢谢!