狂野飙车6鸿蒙版
471.84M · 2025-10-31
大家好,我是小米,今年 31 岁,一个喜欢写代码、讲故事、分享技术的程序员。最近我们商城要做一个大升级:在商品列表的左侧,加一个 商品类目树。
说起来,可能你觉得类目树很常见,淘宝、京东、拼多多都有,点开左侧的“手机数码”、“服饰鞋包”、“家用电器”,右边商品就会动态刷新。但真正自己去做的时候,才发现这背后其实是个大坑:
一句话:既要快,又要准,还要实时!
于是,我们决定用 Spring + Elasticsearch 的聚合 来搞定。接下来,我就带大家走一遍我们的踩坑之旅和最终的技术方案。
一开始,需求刚提出来,我们的直觉是:
比如下面这条 SQL:
乍一看没问题,但当我们实际跑到线上时,MySQL 就直接跪了:
于是,方案一票否决。
我们换个思路。既然要做实时统计和聚合,那 Elasticsearch 正好是擅长的领域:
所以,最终我们决定用 Spring Boot + Elasticsearch 来做。
在讲技术实现之前,先聊聊类目树的数据长什么样。
比如我们的商城类目结构:
每个节点都要展示:
所以,我们需要在 Elasticsearch 里把商品的类目信息存进去。一般存法是:
这里的 category_path 非常关键,它表示商品所在的完整类目路径。这样我们才能按父级类目统计商品数。
接下来就是重头戏:如何统计类目下的商品数。
我们用的是 Terms Aggregation。比如,统计一级类目的商品数,可以这样写:
这个查询的意思是:按 category_path 聚合,统计每个类目下的商品数量。
如果要结合搜索条件,比如用户搜了“iPhone”,就可以直接加上:
这样,返回结果里就是:
聊完了原理,我们来点代码。我们用的是 Spring Data Elasticsearch。
1. 配置依赖
2. 定义实体类
3. 编写聚合查询
这样,我们就能实时拿到每个类目下的商品数了。
当然,实际做的时候我们也遇到不少问题。
1. 类目层级太深
如果类目有三级甚至四级,直接聚合会很慢。我们用了 子聚合(Sub Aggregation) 来做。
这样可以逐级展开,性能会好很多。
2. 热点类目查询太频繁
比如“手机数码”点击太多,我们加了一层 缓存:
3. 分片 & 副本优化
Elasticsearch 的分片数我们按数据量调优,确保查询分布均匀,避免单点热点。
类目树功能上线后,用户体验大大提升:
而且,最让我自豪的是,之前大家觉得“类目树就是个 UI 样式”,现在都觉得背后是门学问,哈哈。
这次的类目树项目,我学到几点:
如果你们的项目里,也有类似的 “实时统计”、“大数据聚合” 需求,Elasticsearch 一定要学会。
以上就是小米今天的分享。希望能帮到你们,如果你们在做类目树或者 Elasticsearch 聚合时遇到坑,欢迎留言交流!
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!