news 2026/10/20 2:18:55

【DIY系列:自己动手写分布式搜索引擎】第03篇:从敲下关键词到看到结果:一次搜索的完整旅程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【DIY系列:自己动手写分布式搜索引擎】第03篇:从敲下关键词到看到结果:一次搜索的完整旅程

上一篇:【第02篇】搜索引擎的五脏六腑:核心模块全景图
下一篇:【第04篇】网络爬虫:给搜索引擎当采风人


摘要

你敲下"无线耳机",回车,零点几秒后结果就铺满了屏幕。这零点几秒里,搜索引擎并没有临时去翻遍几十亿网页,它早就把功课做在前面了。本文把一次搜索拆成离线和在线两条时间线,带你看看文档是怎么悄悄进索引的,查询又是怎么秒回的,顺便聊聊同步建索引和异步建索引那点事。

一、把一次搜索拆成两条时间线

理解搜索引擎最关键的一招,是分清两条时间线。

一条是离线时间线:在你看不见的时候,系统把文档抓取、解析、分词、建索引。这条线可能持续几小时、几天,跑一次或定期跑。

另一条是在线时间线:你敲下关键词的那一刻,系统读现成的索引、合并、打分、返回。这条线要求极快,几百毫秒内必须出结果。

【离线 vs 在线】 离线(看不见的苦力) 在线(用户感知的部分) ───────────────── ────────────────── 爬虫抓网页 → 清洗 → 分词 用户查询 → 分词 → 查倒排 ↓ ↓ 写倒排索引 / 正排 / 列存 合并倒排 → 打分 → 排序 ↓ ↓ 落盘成索引文件 返回前 N 条结果

很多人以为搜索慢,是因为以为查询时要现找。其实查询时只做"读"和"算",重活全在离线阶段干完了。这是搜索引擎快的根本原因。

二、离线那条线:文档是怎么进索引的

离线阶段,一份文档要经历一道流水线。

假设要索引一篇网页。先抓回来原始 HTML,去掉标签、广告、导航这些噪音,得到纯文本。然后把文本切成一个个词(分词),中文尤其麻烦,因为字和字之间没空格。接着,对每个词,把它出现的文档号、出现位置、词频记下来,写进倒排表。

【一篇文档的索引之旅】 原始HTML ──▶ 清洗去噪 ──▶ 分词 │ ▼ 倒排表: 词 → [文档ID, 位置, 词频] 正排表: 文档ID → 标题/正文/URL │ ▼ 落盘成索引文件

注意这里同时产出了倒排表和正排表。倒排表回答"这个词在哪些文档",正排表回答"这个文档长什么样",两者配合,查询时才能既快又完整地返回结果。

三、在线那条线:查询是怎么跑完的

你按下回车的瞬间,在线时间线启动。

系统先把你的查询"无线耳机"分词成"无线"“耳机”(也可能作为一个短语)。然后去倒排表查:含有"无线"的文档有哪些,含有"耳机"的文档有哪些。两个列表做交集,得到同时包含两者的文档候选集。

接下来是关键一步:打分。每个候选文档算一个相关性分。比如"无线"和"耳机"都出现在标题里,分数高;只出现在正文末尾,分数低。最后按分数从高到低排,取前十条返回。

【一次查询的在线流程】 查询 "无线耳机" │ ▼ 分词: [无线, 耳机] │ ▼ 查倒排: 无线→[d1,d3,d7] 耳机→[d1,d2,d7] │ ▼ 合并求交: [d1, d7] ← 同时含两个词 │ ▼ 打分排序: d1(9.2) > d7(7.8) │ ▼ 返回 Top10 结果

整个过程没有遍历全库,全是查表 + 集合运算 + 算术,所以才快。

四、同步建索引 vs 异步建索引

这里有个工程上的选择,值得单独拎出来说。

同步建索引指文档一进来就立刻建索引、立刻可搜。好处是实时,刚发的商品马上能搜到。坏处是写入压力大时,建索引会拖慢主流程。

异步建索引用消息队列解耦:文档先丢进队列,后台消费者慢慢建索引。主流程不受干扰,但新数据要等一小会儿才能搜到。这就是所谓的"近实时"搜索,延迟通常在秒级。

【同步 vs 异步建索引】 同步: 写入 ──▶ 立即建索引 ──▶ 可搜 (实时,但写入被拖累) 异步: 写入 ──▶ 进队列 ──▶ 后台建索引 ──▶ 稍后可搜 (解耦,近实时)

实际系统几乎都选异步,配合一个可调节的刷新间隔(比如每秒刷新一次),在实时性和性能之间找平衡。这个"刷新间隔"后面讲 Lucene 近实时和 ES 写入时会再碰到。

五、为什么搜索快得"不讲道理"

总结一下,搜索引擎的快来自三个设计:

第一,重活前置。建索引时把最耗时的分词、统计全做了,查询时只做轻量的查表和算分。

第二,倒排结构。查询走索引而不是扫全库,复杂度从"文档数"降到了"包含该词的文档数"。

第三,集合运算。多词查询变成倒排链的交集/并集,配合跳表等技巧,长列表也能快速合并。

这三件事加起来,才让你感觉搜索是"瞬间"完成的。

六、在线阶段的隐藏优化:查询改写与缓存

前面把在线流程讲成了标准动作,真实系统里还有两道隐藏工序,值得提前知道,免得后面看 Lucene/ES 时一头雾水。

第一道是查询改写。你输入"无线耳机",系统未必拿原样去查。它可能先做拼写纠错(你手滑打成"无限耳机"也能救回来),再做同义词扩展(“无线耳机"顺带查"蓝牙耳机”),甚至做意图理解(搜"苹果"时判断你要手机还是水果)。这些改写发生在真正查倒排之前,对结果质量影响巨大。本系列后面会专门花篇幅讲纠错和同义词,这里先种个种子。

第二道是缓存。搜索有个好性质:同样的关键词,结果短时间內不会变。于是系统把"查询 → TopN 结果"缓存起来,下次同样的查询直接返回,连倒排都不用查。Lucene 里的 Filter 缓存、ES 的查询结果缓存,都是这个思路。缓存把热点查询的延迟从毫秒级压到微秒级。

【查询改写的顺序】 原始查询 ──▶ 拼写纠错 ──▶ 同义词/意图扩展 ──▶ 真正查倒排 │ 命中缓存? ──▶ 直接返回(跳过查倒排)

再给个直观的延迟概念,免得你对"快"没感觉。假设索引有 1 亿文档,全表扫描一次可能要几秒;用倒排+求交,通常几毫秒到几十毫秒;热点查询再叠加缓存,能到亚毫秒。这三级跳,正是搜索引擎工程价值的体现。

最后提醒一个常见误区:很多人以为搜索慢就去加机器。其实多数搜索慢,不是算力不够,而是索引结构没建对(比如漏了 DocValues、分词太碎),或者查询写法太挫(比如用通配符前缀匹配,逼着扫全词典)。定位清楚再优化,事半功倍。

七、一个被忽视的细节:索引和查询必须用同一把"尺子"

前面讲分词是检索层和索引层都要做的第一步。这里埋了个极易踩的坑:建索引时的分词,和查询时的分词,必须用同一套规则。否则就会出现"明明库里有,却搜不到"的灵异事件。

举个真实例子。建索引时你用智能分词,把"无线耳机"切成了"无线/耳机";查询时你图省事,直接按空格切(用户输入没空格),结果"无线耳机"被当成一个整体词去倒排里查,倒排里根本没有这个词,自然零结果。两边尺子不一样,永远对不上。

【分词不一致的经典翻车】 建索引: "无线耳机" → [无线, 耳机] (存进倒排的是这两个词) 查查询: "无线耳机" → [无线耳机] (去倒排找"无线耳机", 没有!) 结果: 0 条 ← 库里明明有, 却搜不到

所以工程上铁律是:Index 和 Query 共用同一个 Analyzer 实例(或同一套配置)。Lucene 为什么特别强调"index 时用 Analyzer,query 时也要用 Analyzer",根子就在这。这个坑我见过太多人掉进去,调试半天才发现是分词不一致。记住一句话:分词是搜索的入口,入口的尺子,两端必须一致。

本篇小结

一次搜索的真相是两条时间线:离线阶段把文档分词、建倒排和正排、落盘;在线阶段只做分词、查倒排、合并、打分、排序。同步建索引实时但拖累写入,异步建索引解耦却近实时。搜索引擎之所以快,靠的是重活前置、倒排结构、集合运算三板斧。

下一篇,我们去离线时间线的起点看看:网络爬虫是怎么把满世界的网页搬进系统的。


上一篇:【第02篇】搜索引擎的五脏六腑:核心模块全景图
下一篇:【第04篇】网络爬虫:给搜索引擎当采风人


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

腾讯下场,推出股票分析智能体

最近一周AI科技圈又发生了啥新鲜事? Manifold AI推出WorldScape RSI机器人自我改进框架 通过内外两层智能体协作,WorldScape RSI将任务执行、经验复盘、技能修订与动作模型训练连接起来,并在RoboDojo机器人学习基准的Agent赛道登顶。内层根据…

作者头像 李华
网站建设 2026/10/20 2:18:07

PS教程初中高158节:图层蒙版+通道抠图+人像精修+3D文字全套

资源概览 这套Photoshop教程资源是一套结构清晰的系统性学习材料,按照初级、中级、高级三个阶段进行划分,共计158个mp4格式的教学视频,并附带了完整的配套素材文件。无论你是刚接触图像的初学者,还是需要提升技能的设计爱好者&am…

作者头像 李华
网站建设 2026/10/20 2:17:24

2026昌吉软件检测第三方公司排行榜TOP5:软件检测+功能性能测试+信息安全测评+软件验收报告 机构地址及联系方式推荐

昌吉市软件检测机构林立如云,良莠不齐之势显而易见。为助本地开发者、政务单位及中小企客户拨云见日、择善而从,小编历时三周实地踏勘,走访二十余处办公点位,核查资质原件、比对检测案例、暗访服务流程,最终甄选出五家…

作者头像 李华
网站建设 2026/10/20 2:17:05

JSONP协议误用导致的数据泄露原理与治理方案

1. 这不是“劫持”,而是一场被遗忘的协议误用事故“JSONP劫持”这个词在安全圈里流传多年,但说实话,我第一次在某次红队复盘会上听到它时,心里咯噔一下——不是因为多高深,而是因为它背后藏着一个典型的“技术债陷阱”…

作者头像 李华
网站建设 2026/10/20 2:15:02

基于Python的CNN迁移学习实现夏冬季节风景图像分类实战

又是毕设季节。看到“基于Python的卷积神经网络训练识别夏冬季节风景”这个题目,我第一反应是:典型但确实有得做。说它典型,是因为它本质上是图像二分类,夏季和冬季,两个标签,网络结构不用太复杂&#xff1…

作者头像 李华