Java 开发原创文章搜索引擎:Spring Boot 集成 Elasticsearch 的完整流程
·
Java开发原创文章搜索引擎:Spring Boot集成Elasticsearch的完整流程
1. 引言
Elasticsearch作为分布式搜索引擎,为全文检索提供毫秒级响应。结合Spring Boot的自动化配置能力,可快速构建高性能文章搜索引擎。核心优势包括:
- 近实时搜索(NRT)
- RESTful API设计
- 分布式横向扩展能力
- 支持中文分词(如IK Analyzer)
2. 环境准备
| 组件 | 推荐版本 | 备注 |
|---|---|---|
| JDK | 11+ | LTS版本 |
| Spring Boot | 2.7.x | 兼容Spring Data Elasticsearch |
| Elasticsearch | 7.17.x | 与Spring Boot版本匹配 |
3. 项目初始化
3.1 创建Spring Boot项目
使用Spring Initializr生成项目,勾选:
- Spring Web
- Spring Data Elasticsearch
3.2 添加Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- IK中文分词插件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
4. 核心配置
4.1 配置文件application.yml
spring:
elasticsearch:
uris: http://localhost:9200 # ES地址
connection-timeout: 5s # 连接超时
socket-timeout: 30s # 读写超时
# 自定义索引配置
article:
index:
name: article_index
shards: 3
replicas: 1
4.2 中文分词配置
创建IKAnalyzerConfig.java:
@Configuration
public class IKAnalyzerConfig {
@Bean
public ElasticsearchCustomizer customizer() {
return client -> {
Settings settings = Settings.builder()
.put("index.analysis.analyzer.ik.type", "ik_max_word")
.build();
client.putTemplate("ik_template", settings);
};
}
}
5. 数据模型设计
5.1 实体类映射
@Document(indexName = "#{@environment.getProperty('article.index.name')}")
public class Article {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content;
@Field(type = FieldType.Date)
private Date publishTime;
// Getters & Setters
}
注解说明:
@Document:定义ES索引名称(动态读取配置)@Field(analyzer="ik_max_word"):启用中文分词
6. 数据访问层
6.1 Repository接口
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
// 标题关键词搜索
Page<Article> findByTitle(String keyword, Pageable pageable);
// 组合查询:标题+内容
@Query("{\"bool\": {\"must\": [{\"match\": {\"title\": \"?0\"}}, {\"match\": {\"content\": \"?1\"}}]}}")
List<Article> complexSearch(String titleKeyword, String contentKeyword);
}
6.2 自定义Repository实现
public class ArticleCustomRepositoryImpl implements ArticleCustomRepository {
@Autowired
private ElasticsearchOperations operations;
@Override
public List<Article> searchByPhrase(String phrase) {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchPhraseQuery("content", phrase))
.build();
return operations.search(query, Article.class).get().map(SearchHit::getContent).collect(Collectors.toList());
}
}
7. 业务逻辑层
7.1 索引管理服务
@Service
public class IndexService {
@Autowired
private ElasticsearchOperations operations;
public void createIndex() {
operations.indexOps(Article.class).create();
operations.indexOps(Article.class).putMapping();
}
}
7.2 文章搜索服务
@Service
public class SearchService {
@Autowired
private ArticleRepository repository;
public Page<Article> searchArticles(String keyword, int page, int size) {
return repository.findByTitle(keyword, PageRequest.of(page, size, Sort.by("publishTime").descending()));
}
}
8. RESTful API设计
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
@Autowired
private SearchService searchService;
@GetMapping("/search")
public ResponseEntity<Page<Article>> search(
@RequestParam String keyword,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return ResponseEntity.ok(searchService.searchArticles(keyword, page, size));
}
}
9. 高级功能实现
9.1 相关性排序公式
在搜索中按相关性得分排序: $$ score = \frac{\text{TF} \times \text{IDF}}{\text{fieldLength}} $$ 其中:
- TF:词频(Term Frequency)
- IDF:逆文档频率(Inverse Document Frequency)
9.2 高亮显示
SearchHits<Article> hits = operations.search(query, Article.class);
hits.forEach(hit -> {
Map<String, List<String>> highlights = hit.getHighlightFields();
hit.getContent().setTitle(highlights.get("title").get(0));
});
10. 性能优化建议
- 索引设计:
- 冷热数据分离
- 使用
_routing优化分片路由
- 查询优化:
- 避免深度分页(使用
search_after) - 启用查询缓存
- 避免深度分页(使用
- 集群管理:
# 监控API示例 curl -X GET "localhost:9200/_cluster/health?pretty"
11. 完整测试流程
- 启动ES集群:
docker run -d -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.17.10 - 测试API:
GET /api/articles/search?keyword=Spring&page=0&size=5 - 验证响应:
{ "content": [ { "id": "1", "title": "Spring Boot集成指南", "content": "详细教程...", "publishTime": "2023-01-15" } ], "pageable": { /* 分页信息 */ } }
结语
通过Spring Boot与Elasticsearch的深度集成,可快速构建支持中文分词、高亮显示、相关性排序的原创文章搜索引擎。后续可扩展:
- 实时索引更新(使用RabbitMQ消息队列)
- 多维度聚合分析
- 个性化推荐算法集成
提示:生产环境建议使用Elastic Cloud托管服务,简化集群运维管理。
更多推荐
所有评论(0)