news 2026/4/16 13:48:02

搜索慢了?SpringBoot+Elasticsearch让查询快100倍!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
搜索慢了?SpringBoot+Elasticsearch让查询快100倍!

《搜索慢了?SpringBoot+Elasticsearch让查询快100倍!》

我是小坏,今天咱们聊搜索。用户搜个东西,转圈圈等半天,这体验可不行。数据库like查询是方便,但数据多了能把你卡死。今天教你用Elasticsearch(后面就叫ES),让搜索快到飞起。

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

一、数据库搜索的痛

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

场景:1000万商品,搜索"华为手机"

SELECT*FROMproductsWHEREnameLIKE'%华为%'ORdescriptionLIKE'%华为%';

问题

  • 全表扫描,不走索引
  • 返回慢,用户等3秒
  • 不能分词(“华为手机"搜不到"华为P40手机”)
  • 不能按相关度排序
  • 不支持拼音搜索

用ES能解决啥

  • 毫秒级返回
  • 自动分词
  • 支持拼音、同义词
  • 智能排序
  • 聚合统计

二、ES快速上手

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

2.1 先明白几个词

  1. 索引:相当于数据库
  2. 文档:相当于一行数据
  3. 字段:相当于列
  4. 分词:把句子拆成词,比如"华为手机"拆成"华为"和"手机"

2.2 3步集成

第一步:加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>

第二步:写配置

spring:elasticsearch:uris:http://localhost:9200username:elasticpassword:123456

第三步:定义商品实体

@Document(indexName="product")@DatapublicclassProduct{@IdprivateLongid;@Field(type=FieldType.Text,analyzer="ik_max_word")privateStringname;// 商品名,用ik分词@Field(type=FieldType.Text,analyzer="ik_max_word")privateStringdescription;// 描述@Field(type=FieldType.Double)privateDoubleprice;@Field(type=FieldType.Keyword)privateStringcategory;// 分类,不分词@Field(type=FieldType.Integer)privateIntegersales;// 销量}

三、数据同步:4种方案选哪个?

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

3.1 双写(简单直接)

@ServicepublicclassProductService{publicvoidaddProduct(Productproduct){// 1. 写数据库productRepository.save(product);// 2. 写ESelasticsearchRepository.save(product);}}

优点:实时性强
缺点:可能不一致,影响性能

3.2 定时同步(稳定可靠)

@ComponentpublicclassSyncTask{@Scheduled(fixedDelay=300000)// 5分钟一次publicvoidsyncProducts(){// 查最近5分钟修改的商品List<Product>products=productRepository.findRecentUpdated();elasticsearchRepository.saveAll(products);}}

优点:解耦,稳定
缺点:有延迟

3.3 消息队列(推荐)

商品更新发消息,消费者同步到ES。解耦,实时,但复杂。

3.4 监听binlog(高级玩法)

监听数据库变化自动同步。实时,对业务无侵入,但技术门槛高。

建议:中小项目用双写或定时同步,大项目用消息队列。

四、搜索实战

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

4.1 基础搜索

@ServicepublicclassProductSearchService{publicPage<Product>search(Stringkeyword,intpage,intsize){// 构建查询NativeSearchQueryquery=newNativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(keyword,"name","description")).withPageable(PageRequest.of(page,size)).build();returnelasticsearchRestTemplate.search(query,Product.class);}}

4.2 多字段搜索+高亮

publicSearchResultsearchProducts(Stringkeyword,intpage,intsize){// 1. 多字段匹配MultiMatchQueryBuilderquery=QueryBuilders.multiMatchQuery(keyword).field("name",3.0f)// name权重3倍.field("description",1.0f);// 2. 高亮显示HighlightBuilderhighlightBuilder=newHighlightBuilder().field("name").preTags("<em>").postTags("</em>");NativeSearchQuerysearchQuery=newNativeSearchQueryBuilder().withQuery(query).withHighlightBuilder(highlightBuilder).withPageable(PageRequest.of(page,size)).build();// 执行搜索SearchHits<Product>searchHits=elasticsearchRestTemplate.search(searchQuery,Product.class);// 封装结果returnconvertToResult(searchHits);}

4.3 拼音搜索

步骤

  1. 安装拼音分词插件
  2. 字段用拼音分词器
  3. 搜索时同时匹配中文和拼音
// 搜索时同时查中文和拼音String[]fields={"name","name.pinyin","description","description.pinyin"};MultiMatchQueryBuilderquery=QueryBuilders.multiMatchQuery(keyword,fields);

4.4 同义词搜索

场景:搜"笔记本"也能找到"笔记本电脑"

// 同义词配置"filter":{"my_synonym":{"type":"synonym","synonyms":["笔记本,笔记本电脑","手机,移动电话"]}}

五、排序和筛选

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

5.1 智能排序

// 按相关度、销量、价格综合排序NativeSearchQueryquery=newNativeSearchQueryBuilder().withSort(SortBuilders.scoreSort())// 相关度.withSort(SortBuilders.fieldSort("sales").order(SortOrder.DESC))// 销量.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC))// 价格.build();

5.2 条件筛选

// 价格区间RangeQueryBuilderpriceFilter=QueryBuilders.rangeQuery("price").gte(minPrice).lte(maxPrice);// 分类筛选TermQueryBuildercategoryFilter=QueryBuilders.termQuery("category",category);// 组合查询BoolQueryBuilderboolQuery=QueryBuilders.boolQuery().must(QueryBuilders.multiMatchQuery(keyword,"name","description")).filter(priceFilter).filter(categoryFilter);

六、聚合分析

场景:搜索结果的分类统计,用于生成筛选条件

publicMap<String,Long>getCategoryStats(Stringkeyword){// 按分类聚合TermsAggregationBuilderaggregation=AggregationBuilders.terms("by_category").field("category").size(10);NativeSearchQueryquery=newNativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(keyword,"name","description")).addAggregation(aggregation).build();SearchHits<Product>searchHits=elasticsearchRestTemplate.search(query,Product.class);// 解析聚合结果Termsterms=searchHits.getAggregations().get("by_category");Map<String,Long>result=newHashMap<>();for(Terms.Bucketbucket:terms.getBuckets()){result.put(bucket.getKeyAsString(),bucket.getDocCount());}returnresult;}

七、性能优化

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

7.1 索引优化

@Document(indexName="product",createIndex=true,shards=3,// 分片数replicas=1)// 副本数publicclassProduct{// 字段优化@Field(type=FieldType.Keyword)privateStringsku;// 精确查找用keyword@Field(type=FieldType.Integer,index=false)privateIntegerstock;// 不索引库存,只用于显示}

7.2 查询优化

// 避免深度分页SearchAfterBuildersearchAfter=newSearchAfterBuilder();searchAfter.setSortValues(newObject[]{lastScore,lastId});// 使用filter替代query(不计算分数,可缓存)BoolQueryBuilderboolQuery=QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name",keyword)).filter(QueryBuilders.termQuery("status",1));// 状态过滤用filter

7.3 缓存优化

@ServicepublicclassProductSearchService{@Cacheable(value="search",key="#keyword + ':' + #page")publicPage<Product>search(Stringkeyword,intpage,intsize){// 热门搜索结果缓存returndoSearch(keyword,page,size);}}

八、监控告警

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

8.1 健康检查

# application.ymlmanagement:endpoints:web:exposure:include:health,metricselasticsearch:health:enabled:true

8.2 关键指标监控

  • 查询响应时间
  • 索引速度
  • 节点负载
  • 磁盘使用率

8.3 告警规则

@ComponentpublicclassESMetricsMonitor{@Scheduled(fixedRate=60000)publicvoidcheckHealth(){// 检查集群状态ClusterHealthhealth=elasticsearchRestTemplate.cluster().health();if(health.getStatus()==ClusterHealthStatus.RED){// 发送告警alertService.send("ES集群异常,状态:"+health.getStatus());}// 检查查询延迟doubleavgQueryTime=getAverageQueryTime();if(avgQueryTime>1000){// 超过1秒alertService.send("ES查询延迟过高:"+avgQueryTime+"ms");}}}

九、实战:电商搜索完整流程

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

9.1 搜索建议

publicList<String>getSuggestions(Stringprefix){CompletionSuggestionBuildersuggestion=SuggestBuilders.completionSuggestion("suggest").prefix(prefix).size(5);SuggestBuildersuggestBuilder=newSuggestBuilder().addSuggestion("product_suggest",suggestion);SearchRequestrequest=newSearchRequest("product").source(newSearchSourceBuilder().suggest(suggestBuilder));// 执行搜索建议SearchResponseresponse=elasticsearchRestTemplate.suggest(request,RequestOptions.DEFAULT);// 解析结果returnparseSuggestions(response);}

9.2 搜索结果封装

@DatapublicclassSearchResult{privateList<ProductVO>products;// 商品列表privateList<CategoryAgg>categories;// 分类统计privateList<BrandAgg>brands;// 品牌统计privatePriceRangepriceRange;// 价格区间privatelongtotal;// 总条数privateinttotalPage;// 总页数privateList<String>suggestions;// 搜索建议}// 搜索接口@GetMapping("/search")publicSearchResultsearch(@RequestParamStringkeyword,@RequestParam(defaultValue="0")intpage,@RequestParam(defaultValue="20")intsize,@RequestParam(required=false)Stringcategory,@RequestParam(required=false)DoubleminPrice,@RequestParam(required=false)DoublemaxPrice){returnproductSearchService.search(keyword,page,size,category,minPrice,maxPrice);}

十、今日要点

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

  1. ES比数据库like快得多,支持分词、拼音、同义词
  2. 数据同步4种方案:双写简单,定时稳定,消息队列推荐
  3. 搜索要智能:多字段、高亮、拼音、同义词
  4. 排序和筛选是电商搜索的刚需
  5. 聚合分析用于生成筛选条件
  6. 性能优化:索引设计、查询优化、缓存
  7. 监控告警不能少,出问题早知道

十一、避坑指南

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

坑1:分词器选错

// ❌ 错误:用默认分词器分中文@Field(type=FieldType.Text)// 默认分词器处理不好中文// ✅ 正确:用ik分词器@Field(type=FieldType.Text,analyzer="ik_max_word")

坑2:字段类型用错

// ❌ 错误:分类用Text,搜索时会分词@Field(type=FieldType.Text)privateStringcategory;// ✅ 正确:分类用Keyword,精确匹配@Field(type=FieldType.Keyword)privateStringcategory;

坑3:分页太深

// ❌ 错误:深度分页性能差from:10000,size:20// 性能差// ✅ 正确:用search_aftersearch_after:[lastScore,lastId]

十二、思考题

场景:你要做一个商品搜索,要求:

  1. 支持中文、拼音、同义词
  2. 结果按综合排序(相关度+销量+价格)
  3. 左侧有分类、品牌、价格筛选
  4. 搜索框有智能提示
  5. 热门搜索词推荐

问题

  1. 你会如何设计ES索引?
  2. 如何实现拼音和同义词搜索?
  3. 如何优化搜索性能?

评论区聊聊你的方案,明儿咱们讲MyBatis-Plus。


明天预告:《SpringBoot+MyBatis-Plus:开发效率提升10倍》

今日福利:关注后回复"ES搜索",获取电商搜索完整源码和ik分词器配置。


CSDN运营小贴士:

💡互动

  1. 你的项目搜索用的是什么方案?
  2. 遇到过哪些搜索性能问题?
  3. 留言提问,明天文章解答

👥进群
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 11:04:06

Segment Anything终极指南:零基础掌握AI图像分割的完整方法

Segment Anything终极指南&#xff1a;零基础掌握AI图像分割的完整方法 【免费下载链接】segment-anything The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example no…

作者头像 李华
网站建设 2026/4/15 5:35:04

如何在Zotero中实现PDF文档实时翻译?3步安装指南

如何在Zotero中实现PDF文档实时翻译&#xff1f;3步安装指南 【免费下载链接】ZoteroPDFTranslate插件下载 Zotero PDF Translate 插件下载本仓库提供了一个用于 Zotero 的 PDF Translate 插件的 .xpi 文件下载 项目地址: https://gitcode.com/open-source-toolkit/3d2b0 …

作者头像 李华
网站建设 2026/4/14 15:27:28

完整掌握NYC代码覆盖率:从基础配置到高级定制实战

完整掌握NYC代码覆盖率&#xff1a;从基础配置到高级定制实战 【免费下载链接】nyc the Istanbul command line interface 项目地址: https://gitcode.com/gh_mirrors/ny/nyc 在现代JavaScript开发中&#xff0c;代码覆盖率分析已成为保证软件质量的关键环节。NYC作为Is…

作者头像 李华
网站建设 2026/4/13 9:28:28

notepad++实用技巧

0、大小写转换1、Notepad的实用技巧 https://blog.csdn.net/so_geili/article/details/79317001#%E4%B9%9D%E4%BF%9D%E6%8C%81notepad%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE%E9%A3%8E%E6%A0%BC%E5%88%B0%E7%BD%91%E9%A1%B5%E6%88%96word%E4%B8%AD 目录 一 安装notepad 二 快捷键…

作者头像 李华
网站建设 2026/4/14 0:04:21

Evolve项目完整安装指南:从零开始快速上手数据库迁移

Evolve项目完整安装指南&#xff1a;从零开始快速上手数据库迁移 【免费下载链接】Evolve lecaillon/Evolve: 是一个基于遗传算法的简单演化计算框架&#xff0c;可以用于解决优化问题。适合用于学习和研究演化计算和优化问题&#xff0c;以及进行相关的算法实现和实验。 项目…

作者头像 李华
网站建设 2026/4/16 14:29:48

在数字中国建设大潮中,科技服务机构如何借助闭环的知识产权智能运营平台解决运营成本攀升,达成融通客户留存率,最终融通完善价值评估体系?

观点作者&#xff1a;科易网AI技术转移研究院在数字中国建设的大背景下&#xff0c;科技服务机构面临着运营成本攀升、客户留存率难以提升、价值评估体系不完善等多重挑战。如何借助闭环的知识产权智能运营平台&#xff0c;解决这些问题&#xff0c;成为科技服务机构亟待解决的…

作者头像 李华