Spring Boot整合Elasticsearch实现高性能模糊搜索(附完整代码)

237 阅读3分钟

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-web

2️⃣ 实体类映射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倍吞吐量!