[Java实战]Spring Boot整合Elasticsearch(二十六)
摘要:本文通过完整的实战演示,详细讲解如何在Spring Boot项目中整合Elasticsearch,实现数据的存储、检索和复杂查询功能。包含版本适配方案、Spring Data Elasticsearch高级特性以及性能优化建议。
一、Elasticsearch核心概念与优势
1.1 为什么要选择Elasticsearch?
- 近实时搜索:数据变更后1秒内即可被检索
- 分布式架构:天然支持水平扩展,轻松应对海量数据
- 全文检索能力:基于倒排索引,支持模糊查询、同义词、分词等
- 多数据类型:支持结构化、非结构化和地理空间数据
1.2 核心概念解析
概念 | 类比关系型数据库 | 说明 |
---|---|---|
Index | Database | 数据容器,包含多个文档类型 |
Type | Table | 7.x版本后已废弃 |
Document | Row | 数据的基本单元 |
Field | Column | 文档的字段 |
Shard | 分区 | 索引的横向拆分单元 |
二、环境准备与版本适配
2.1 组件版本选择
- Spring Boot 2.7.x
- Elasticsearch 7.10.x
- Spring Data Elasticsearch 4.4.x
<!-- pom.xml 依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2.2 配置Elasticsearch连接
# application.yml
spring:elasticsearch:uris: http://localhost:9200username: elasticpassword: your_password
三、实现数据存储与检索
3.1 定义领域模型
@Document(indexName = "articles")
public class Article {@Idprivate String id;@Field(type = FieldType.Text)private String title;@Field(type = FieldType.Keyword)private String category;@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)private LocalDateTime createTime;
}
3.2 创建Repository接口
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {// 自定义查询方法List<Article> findByTitleContaining(String keyword);@Query("{\"match\": {\"title\": {\"query\": \"?0\"}}}")Page<Article> searchByTitle(String keyword, Pageable pageable);
}
3.3 基础CRUD操作示例
@Service
@RequiredArgsConstructor
public class ArticleService {@Autowiredprivate ArticleRepository repository;public void save(Article article) {repository.save(article);}public Page<Article> search(String keyword, int page, int size) {return (Page<Article>) repository.searchByTitle(keyword,PageRequest.of(page, size, Sort.by("createTime").descending()));}
3.4 controller编写
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;//保存数据@PostMapping("/saveArt")public void saveArtInfo(@RequestBody Article art){Article article = new Article();article.setTitle("Spring Boot整合Elasticsearch实战");article.setCategory("技术文章");article.setCreateTime(LocalDateTime.now());System.out.println("=======保存数据======");articleService.save(article);// 查询所有文档//articleService.findAllArticles();}
}
3.5 接口测试
#post请求
http://localhost:8080/art/saveArt
ES中查看数据:
curl -X GET "localhost:9200/articles/_search?pretty"
四、高级查询实战
4.1 组合查询(Bool Query)
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title", "Spring")).filter(QueryBuilders.rangeQuery("createTime").gte("now-7d/d"));queryBuilder.withQuery(boolQuery);
SearchHits<Article> hits = elasticsearchOperations.search(queryBuilder.build(), Article.class);
4.2 聚合分析示例
TermsAggregationBuilder categoryAgg = AggregationBuilders.terms("category_count").field("category.keyword").size(10);NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(categoryAgg).build();SearchHits<Article> searchHits = elasticsearchOperations.search(searchQuery, Article.class);
Terms terms = searchHits.getAggregations().get("category_count");
五、性能优化建议
-
索引策略优化
- 合理设置分片数(建议每个分片大小在10-50GB)
- 使用别名实现零停机索引切换
-
查询优化技巧
- 避免深度分页(推荐使用search_after)
- 使用filter上下文缓存高频过滤条件
-
硬件配置推荐
- SSD硬盘优先
- JVM堆内存不超过32GB
- 预留50%内存给文件系统缓存
六、常见问题排查
Q1:出现NoNodeAvailableException异常
- 检查ES集群状态:
GET _cluster/health
- 验证网络连接和防火墙设置
Q2:查询结果不符合预期
- 使用Analyze API验证分词效果:
POST _analyze {"analyzer": "ik_max_word","text": "分布式搜索引擎" }
参考文献:
- Elasticsearch官方文档
- Spring Data Elasticsearch官方指南
如果你在使用过程中遇到任何问题,欢迎在评论区留言交流。感谢你的阅读,希望这篇文章对你有所帮助!