814 字
约 2 分钟
6
S13-B01 · 倒排索引与基本概念
适用读者:想搞清楚"为什么不能拿数据库做全文搜索"的人。本系列第一篇。
前置:S11 ✅(索引与 EXPLAIN)。
实测环境:Elasticsearch 8.15.3(单节点容器),2026-11-05。
覆盖旧文:482(40) 1845(84) 1551(27) = 151 点。
覆盖扩展:E-S13-001(倒排索引 vs 正排)、E-S13-002(近实时)。
下一篇:S13-B02 · 索引映射与中文分词。
1. 一句话结论
数据库的索引是"从 id 找行"(正排),搜索引擎的索引是"从词找 id"(倒排)。要"按内容里的词找文档",就必须有倒排索引。
| 索引 | 方向 | 适合 |
|---|---|---|
| B+ 树(MySQL) | key → row | 等值/范围 |
| 倒排(ES) | term → doc list | 全文检索、相关性排序 |
"为什么 like '%关键词%' 不行":它只能全表扫描(S11-J02 实测 20,000 行),而倒排是"直接拿到包含该词的文档列表"。
2. 近实时:写入不等于可搜(E-S13-002)
实测(refresh_interval: -1 关闭自动刷新):
写入 3 条后,不 refresh 直接 _count → count: 0
POST /articles/_refresh 之后 → count: 3
| 概念 | 说明 |
|---|---|
_doc 写入 |
先进 translog + memory buffer |
| refresh | 生成新的 segment(可搜),默认每秒一次 |
| flush | 落盘 + 清 translog(更重) |
"为什么刚写入马上查不到":默认 1 秒刷新间隔。需要立刻可见 → 写入时 refresh=true(性能代价)。
3. 实测:分词与查询的匹配关系
分词器输出(standard):
"Elasticsearch tutorial" → ['elasticsearch', 'tutorial']
查询对比:
match "Tutorial"(大写) → 1 ← 会分词+小写
term "Tutorial"(大写) → 0 ← 不分词,直接找 token
term "tutorial"(小写) → 1
match_phrase "elasticsearch tutorial" → 1
match_phrase "tutorial elasticsearch" → 0 ← 顺序敏感
这张表就是 B03 的核心:match 走分析器,term 不走。
4. 核心概念速查
| 概念 | 说明 |
|---|---|
| index | 类似"数据库表",但有自己的分片与 mapping |
| mapping | 字段类型与分词器(B02) |
| shard / replica | 分片 / 副本(J02) |
| segment | Lucene 的不可变小索引;合并是 J01 |
| doc | JSON 文档(ES 8 已无 type 概念) |
5. 五个误区
| 误区 | 真相 |
|---|---|
| "ES 是数据库" | 不是事务型存储(无跨文档事务) |
| "写入就能搜到" | 需 refresh(默认 1 秒) |
"term 和 match 一样" |
前者不分词 |
| "ES 8 还有 type" | 已移除(统一 _doc) |
"like 也能做搜索" |
全表扫描,且无相关性排序 |
6. 自检
- 正排与倒排的区别?
- 写入后为什么可能查不到?
refresh与flush的差别?- 实测里
term "Tutorial"为什么是 0? - ES 8 的 type 发生了什么变化?
7. 下一篇
S13-B02 · 索引映射与中文分词
概念讲完,下一篇讲"中文为什么搜不到":mapping 与 ik 分词器。
本篇属于系列《S13 · 搜索与文档存储》。旧文来源:A-482/1845/1551;扩展点 E-S13-001/002。count 与分词输出为 ES 8.15.3 实测。
S13-B01 · 倒排索引与基本概念
https://www.clxhxhhr.top/posts/5360/ 评论
0 条
还没有评论,先写一条吧。