🧑 博主简介:历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,
15年
工作经验,精通Java编程
,高并发设计
,Springboot和微服务
,熟悉Linux
,ESXI虚拟化
以及云原生Docker和K8s
,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
Springboot整合Elasticsearch 构建文章和古诗词搜索引擎
在数字化时代,快速准确地检索文章和古诗词对于文学爱好者和研究者来说至关重要。Elasticsearch
作为一个强大的搜索和分析引擎,可以帮助我们轻松构建高效的搜索引擎。本文将介绍如何使用 Spring Boot
整合 Elasticsearch
来设计文章和古诗词搜索引擎的索引结构,并提供详细的代码示例和测试输出。
一、索引设计思路
(一)确定数据特点
文章和古诗词数据具有以下特点:
- 标题:简洁地概括内容主题。
- 作者:对于理解作品的背景和风格很重要。
- 内容:搜索的主要对象。
- 类型:区分文章和古诗词。
- 朝代(仅适用于古诗词):有助于筛选特定历史时期的作品。
(二)设计索引结构
根据数据特点,我们可以设计以下索引结构:
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"author": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"type": {
"type": "keyword"
},
"dynasty": {
"type": "keyword",
"null_value": "unknown"
}
}
}
}
核心字段解释:
title
:文本类型,使用ik_max_word
分析器进行索引,ik_smart
分析器进行搜索,以便更好地处理中文分词。author
:同title
,用于存储作者信息。content
:存储文章或古诗词的具体内容。type
:关键字类型,用于区分文章和古诗词。dynasty
:仅适用于古诗词,关键字类型,允许为空值,默认为unknown
。
二、代码示例讲解
(一)项目搭建
- 创建一个 Spring Boot 项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
(二)实体类
创建一个实体类来表示文章或古诗词:
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Document(indexName = "article_poetry_index", type = "_doc")
public class ArticlePoetry {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String title;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String author;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String content;
@Field(type = FieldType.Keyword)
private String type;
@Field(type = FieldType.Keyword, nullValue = "unknown")
private String dynasty;
}
(三)Repository 接口
创建一个 Repository 接口来操作实体类:
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface ArticlePoetryRepository extends ElasticsearchRepository<ArticlePoetry, String> {
}
(四)服务类
创建一个服务类来实现搜索功能:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SearchService {
@Autowired
private ArticlePoetryRepository articlePoetryRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
public List<ArticlePoetry> search(String keyword) {
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(matchQuery("title", keyword).operator(Operator.AND)
.boost(2f)
.analyzer("ik_smart")
.minimumShouldMatch("80%"))
.withQuery(matchQuery("author", keyword).operator(Operator.AND)
.boost(1.5f)
.analyzer("ik_smart")
.minimumShouldMatch("80%"))
.withQuery(matchQuery("content", keyword).operator(Operator.AND)
.boost(1f)
.analyzer("ik_smart")
.minimumShouldMatch("80%"));
NativeSearchQuery query = queryBuilder.build();
return elasticsearchTemplate.queryForList(query, ArticlePoetry.class);
}
}
(五)控制器类
创建一个控制器类来暴露搜索接口:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class SearchController {
@Autowired
private SearchService searchService;
@GetMapping("/search")
public List<ArticlePoetry> search(@RequestParam String keyword) {
return searchService.search(keyword);
}
}
三、测试输出
(一)数据导入
假设我们有以下文章和古诗词数据:
文章:
- 标题:《Spring Boot 实战指南》
- 作者:张三
- 内容:这是一本关于 Spring Boot 的实用指南。
- 类型:文章
古诗词:
- 标题:《静夜思》
- 作者:李白
- 内容:床前明月光,疑是地上霜。举头望明月,低头思故乡。
- 类型:古诗词
- 朝代:唐朝
我们可以通过以下方式将数据导入到 Elasticsearch:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DataImporter {
@Autowired
private ArticlePoetryRepository articlePoetryRepository;
public void importData() {
ArticlePoetry article = new ArticlePoetry();
article.setTitle("《Spring Boot 实战指南》");
article.setAuthor("张三");
article.setContent("这是一本关于 Spring Boot 的实用指南。");
article.setType("文章");
articlePoetryRepository.save(article);
ArticlePoetry poetry = new ArticlePoetry();
poetry.setTitle("《静夜思》");
poetry.setAuthor("李白");
poetry.setContent("床前明月光,疑是地上霜。举头望明月,低头思故乡。");
poetry.setType("古诗词");
poetry.setDynasty("唐朝");
articlePoetryRepository.save(poetry);
}
}
在项目启动时调用 DataImporter
的 importData
方法来导入数据。
(二)测试搜索
启动项目后,我们可以通过访问 /search?keyword=Spring Boot
来测试搜索功能。预期输出如下:
[
{
"id":"<文章的 ID>",
"title":"《Spring Boot 实战指南》",
"author":"张三",
"content":"这是一本关于 Spring Boot 的实用指南。",
"type":"文章",
"dynasty":"unknown"
}
]
如果搜索 keyword=李白
,输出如下:
[
{
"id":"<古诗词的 ID>",
"title":"《静夜思》",
"author":"李白",
"content":"床前明月光,疑是地上霜。举头望明月,低头思故乡。",
"type":"古诗词",
"dynasty":"唐朝"
}
]
四、总结
通过以上步骤,我们成功地使用 Spring Boot
整合 Elasticsearch
构建了一个文章和古诗词搜索引擎。我们设计了合理的索引结构,包括核心字段如标题、作者、内容、类型和朝代(注意,该字段仅适用于古诗词
)。通过代码示例和测试输出,我们展示了如何实现数据导入和搜索功能。在实际应用中,可以根据具体需求进一步优化搜索算法和用户界面,以提供更好的搜索体验。