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. 自检

  1. 正排与倒排的区别?
  2. 写入后为什么可能查不到?
  3. refresh 与 flush 的差别?
  4. 实测里 term "Tutorial" 为什么是 0?
  5. 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/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。