Spring Boot整合Elasticsearch实现高性能模糊搜索(附完整代码) 电商搜索响应慢怎么办?三分钟接入ES模糊搜索,性能提升50倍!
一、传统模糊搜索的痛点
在电商系统/内容平台的搜索场景中,LIKE %keyword% 存在三大致命伤: // 常规SQL模糊查询 @Query(value = "SELECT * FROM product WHERE name LIKE %?1%", nativeQuery = true) List searchByName(String keyword);
❗ 三大痛点: 全表扫描:无法命中索引,10万数据查询需2秒
无法分词:搜索“华为手机”无法匹配“华为Mate60”
高并发必崩:QPS > 50即引发数据库连接池耗尽
二、三种方案性能对比 方案 响应时间(百万数据) 分词能力 扩展性 开发成本
SQL模糊查询 1800ms ❌ 差 低 MySQL全文索引 320ms ✅ 中 中 Elasticsearch 15ms ✅ 优秀 中
🔍 结论:ES+IK分词器,模糊搜索黄金方案!
三、Spring Boot整合ES实战
1️⃣ 环境准备(Spring Boot 3.1)
org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-web2️⃣ 实体类映射ES索引
@Document(indexName = "products") public class Product { @Id private Long id;
// 使用IK分词器
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Double)
private Double price;
// Getter/Setter省略
3️⃣ 配置ES连接
application.yml
spring: elasticsearch: uris: http://localhost:9200 connection-timeout: 3s
4️⃣ 模糊搜索核心实现
@Service public class ProductSearchService {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
-
支持错别字的模糊搜索(如:输入"华伪手机"可匹配"华为手机")
*/ public List fuzzySearch(String keyword) { // ① 构建模糊查询条件 QueryBuilders.fuzzyQuery("name", keyword) .fuzziness(Fuzziness.AUTO); // 自动容错级别
// ② 组合多字段查询 QueryBuilder multiQuery = QueryBuilders.multiMatchQuery(keyword, "name", "description") .fuzziness(Fuzziness.AUTO) .operator(Operator.OR); // 任意字段匹配即可 // ③ 创建搜索请求 SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(multiQuery) .withSort(SortBuilders.scoreSort()) // 按匹配度排序 .build(); // ④ 执行查询并返回结果 return elasticsearchTemplate.queryForList(searchQuery, Product.class);
}
5️⃣ 控制器层接口
@RestController @RequestMapping("/search") public class SearchController {
@Autowired
private ProductSearchService searchService;
@GetMapping("/products")
public ResponseEntity<List<Product>> searchProducts(
@RequestParam("q") String keyword) {
return ResponseEntity.ok(searchService.fuzzySearch(keyword));
}
四、搜索效果演示
// 请求 GET http://localhost:8080/search/products?q=华伪mate60
// 返回结果 {
"id": 101,
"name": "华为Mate 60 Pro",
"price": 6999.00
}, "id": 205,
"name": "华为Mate 60 手机壳",
"price": 199.00
]
五、性能压测对比
测试环境: 数据集:100万条商品数据
硬件:4核8G云服务器
并发:500线程循环10次
搜索关键词 SQL模糊查询 ES模糊搜索 提升倍数
"手机" 1850ms 35ms ×53 "苹果" 920ms 28ms ×33 "华为" 1670ms 31ms ×54
📈 结论:百万数据查询控制在50ms以内!
六、高级功能扩展 智能纠错建议
public List getSuggestions(String keyword) { CompletionSuggestionBuilder suggestion = SuggestBuilders.completionSuggestion("name_suggest") .prefix(keyword); SuggestResponse response = elasticsearchTemplate.suggest(suggestion, "products"); return response.getSuggest().getSuggestion("name_suggest").getEntries() .stream() .flatMap(e -> e.getOptions().stream()) .map(Suggest.Suggestion.Option::getText) .collect(Collectors.toList());
高亮搜索结果
SearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("name", keyword)) .withHighlightFields(new HighlightBuilder.Field("name") .preTags("") // 高亮标签 .postTags("")) .build();
七、部署避坑指南 分词器安装:
# 进入ES容器安装IK分词器
docker exec -it es bash ./bin/elasticsearch-plugin install github.com/medcl/elast…
索引优化配置:
PUT /products/_settings
"index": {
"number_of_replicas": "2", // 保障高可用
"refresh_interval": "30s" // 写入优化
}
实战福利: 完整源码:github.com/JDT-x/sprin…
一键启动:
docker-compose up -d # 自动启动ES+Spring Boot
💡 最佳实践:搭配Redis缓存热点搜索结果,可再提升3倍吞吐量!