连载中 1/20

LIKE 查不了「燕麦拿铁」:为什么需要 Elasticsearch

2026-08-10 · 1691 阅读 · 0 评论 · 0 赞

一个搜索框引发的血案

老王的咖啡商城上线一个月,运营丢来一张截图:用户搜「燕麦拿铁」,搜索结果为空——可商品列表里明明躺着「燕麦拿铁(大杯)」和「燕麦拿铁(双份浓缩)」。用户不会为大杯小杯分两次搜,他要的是一杯咖啡,不是正则表达式。

老王打开商品搜索接口一看,实现朴素得令人心疼:

SELECT * FROM product WHERE name LIKE CONCAT('%', ?, '%');
-- ? 为用户输入的关键词,前后各拼一个 %,两头通配

这一条 SQL,就是本系列第一集的主角反面。

LIKE 模糊查询的三宗罪

第一宗罪:索引用不上。B+ 树索引按列值有序组织,LIKE '燕麦%' 这种前缀匹配还能走索引——树本身就有序,前缀一致就能定位。但 LIKE '%燕麦%' 要求「任意位置包含」,等于让索引放弃有序性去逐条翻书,优化器一看直接放弃,全表扫描伺候。商品表十万条时还能忍,百万条时每次搜索都是一次全表锤炼。

第二宗罪:不懂语义。LIKE 是纯字符串匹配:搜「燕麦拿铁」能命中,搜「拿铁 燕麦」就全军覆没——因为顺序变了字符串就不等了。用户想的是「燕麦」和「拿铁」两个词都满足,不是一串字符精确复现。搜「特价美式」要不要命中「限时特价·经典美式」?按字符匹配,永远差一点。

第三宗罪:没有排序。LIKE 返回的结果没有「谁更相关」的概念,按主键倒序返回,第一条不一定是最好的匹配。搜索体验的一半在排序,而排序需要打分机制——这超出了一台关系数据库的本职。

思路反转:正排变倒排

数据库的存储是正排:一行商品,知道 id 找内容快,知道内容找 id 只能逐行看。搜索要的是反方向:给几个词,快速找出包含这些词的商品。

把三本商品的名字手工分一下词,建一张「词 → 商品」的表:

词条命中的商品
燕麦1(燕麦拿铁大杯)、2(燕麦拿铁双份)、3(燕麦曲奇)
拿铁1、2、4(生椰拿铁)
美式4、5(经典美式)

用户搜「燕麦拿铁」,先分词成「燕麦」「拿铁」,两张表一查一合并:1、2、3、4 号命中,其中 1 和 2 两个词全中——它们显然比只含一个词的 3 和 4 更相关,天然就有了排序依据。这张「词 → 文档」的表,就是倒排索引(Inverted Index)。搜索从「逐条翻书」变成了「查表合并」,复杂度从 O(n) 降到了查词典的量级。

ES 是什么

Elasticsearch(下称 ES)是基于 Lucene 的分布式搜索与分析引擎。Lucene 提供倒排索引这块核心引擎,ES 在它外面套了三层壳:分布式壳(分片、副本、集群)、易用壳(RESTful JSON 接口,curl 就能玩)、生态壳(Kibana、Logstash、Beats)。它能干三件事:全文检索(本系列主线)、结构化过滤(和数据库一样可以精确过滤)、聚合分析(把 GROUP BY 和报表的事也顺手干了)。

它不能替谁干什么

  • 不是数据库替代品:没有事务、不支持外键、写入后近实时可见(不是立即可查),主存储还得是 MySQL;
  • 它管「查」,MySQL 管「存」:写入走 MySQL,变更同步到 ES,查询走 ES——这是 15 篇要展开的经典架构;
  • 别拿它做主键点查:按 id 查一条,MySQL 更快更省,各干各的专业。

本系列的地图

20 篇的路线:先原理(倒排索引、核心概念、分词器、mapping),再查询(match/term/bool、BM25 评分、进阶查询、深分页、聚合),后架构(写入调优、集群、分片规划、数据同步),最后落地(搜索产品化、场景集、陷阱清单、收官地图)。学完这 20 篇,老王的搜索框要从「查无此物」进化到「比我更懂用户想喝什么」。

小结

LIKE 模糊查询的病根:索引用不上、语义读不懂、结果排不了序。药方是把数据结构反转——正排存内容,倒排查词条,搜索从翻书变成查表。下一站把倒排索引拆开看:分词、词典与 posting list,以及评分的直觉从哪来

503

10 年全栈工程师 · 503咖啡馆主理人

#Elasticsearch#搜索#倒排索引#LIKE#全文检索

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞