倒排索引 · 分词映射 · 相关性打分 · 段管理
目 录
一、导读
二、倒排索引原理
2.1 正排 vs 倒排
2.2 倒排索引结构
2.3 示例
三、分词器与映射
3.1 Analyzer 处理流程
3.2 常见分词器
3.3 映射:text vs keyword
四、BM25 相关性打分
4.1 从 TF-IDF 到 BM25
4.2 BM25 公式
4.3 参数含义
五、近实时写入与段管理
5.1 写入路径
5.2 段合并策略
5.3 主分片与副本的一致性
六、聚合分析与本篇小结
6.1 三类聚合
6.2 本篇小结
一、导读
本讲深入 Elasticsearch 内核:检索为何快(倒排索引结构)、文本如何被拆解(分词器与映射)、结果如何排序(BM25 相关性打分)、写入如何高效(近实时与段管理)。理解这些,是建模映射、优化查询与调优性能的基础。
二、倒排索引原理
2.1 正排 vs 倒排
关系库与普通存储采用「正排索引」:以文档为核心记录「文档包含哪些词」,查询某词需逐条扫描。倒排索引反其道而行,以「词项」为核心记录「每个词出现在哪些文档」。可用书籍类比:正排像目录(章节→页码),倒排像书尾索引页(关键词→页码列表),查词直接翻对应页。
2.2 倒排索引结构
倒排索引由三部分协同组成:
组成 | 内容 | 作用 |
词典 Dictionary | 所有不重复词项,支持 FST 压缩 | 定位词项倒排链 |
倒排表 Posting List | 包含该词的文档 ID 列表 | 确定命中文档 |
位置表 Position | 词在文档内的词频、位置与偏移 | 打分、短语、高亮 |
每个词项还会记录文档频率(df)等统计信息,供相关性打分使用。
2.3 示例
// 文档 |
doc1: "NoSQL 实战" |
doc2: "Elasticsearch 实战" |
// 倒排索引(词项 -> 文档列表) |
NoSQL -> [1] |
实战 -> [1, 2] |
Elasticsearch -> [2] |
// 查询"实战"直接定位文档 1、2,无需全表扫描 |
三、分词器与映射
3.1 Analyzer 处理流程
文本在写入前先经「分词器」(Analyzer)处理,由三阶段流水线构成:字符过滤器(Character Filter,如去 HTML 标签)→ 分词器(Tokenizer,按规则切词)→ 词项过滤器(Token Filter,如转小写、去停用词、同义词)。英文与中文的分词策略差异明显。
3.2 常见分词器
分词器 | 适用 | 说明 |
standard | 通用 | 按 Unicode 边界切分,英文友好 |
simple | 英文 | 按非字母字符切分并转小写 |
keyword | 不分词 | 整段作为一个词项 |
ik | 中文 | 中文分词器(smart / max_word) |
whitespace | 特殊 | 仅按空白切分 |
3.3 映射:text vs keyword
映射(Mapping)定义字段类型与分词策略,是「数据的 DNA」:text 字段会分词并建立倒排索引,用于全文检索;keyword 字段不分词、按原值精确匹配,用于过滤、排序与聚合。设计映射时需按查询方式决定用 text 还是 keyword,常用 multi-fields 同时保留两种视图。
PUT /article/_mapping |
{ "properties": { |
"title": { "type": "text", "analyzer": "ik_max_word" }, |
"tag": { "type": "keyword" } |
} } |
四、BM25 相关性打分
4.1 从 TF-IDF 到 BM25
早期 Lucene 使用 TF-IDF 打分,长文档易因词频累积获得不公平高分。Elasticsearch 5.x 起默认改用 BM25(Best Match 25),在词频与文档长度之间取得平衡,成为相关性排序的默认机制。
4.2 BM25 公式
BM25 对每个查询词累加得分,核心公式:
score(D,Q) = Σ IDF(qi) × (fi × (k1 + 1)) |
/ (fi + k1 × (1 - b + b × |D| / avgdl)) |
IDF(qi) = ln(1 + (N - df + 0.5) / (df + 0.5)) |
# k1=1.2 控制词频饱和,b=0.75 控制长度归一化 |
4.3 参数含义
- IDF:逆文档频率,词越稀缺得分越高,抑制高频通用词。
- fi:词在文档中的出现频率,词频越高得分越高(但会饱和)。
- |D| / avgdl:文档长度与平均长度之比,惩罚「用长文档稀释关键词」的情况。
- k1、b:调节参数,ES 默认分别为 1.2 与 0.75。
生产可用 Function Score 或自定义 similar,叠加业务权重(如新品加权、会员加权)微调排序。
五、近实时写入与段管理
5.1 写入路径
写入先进内存缓冲并追加 translog,约 1 秒(refresh)生成可搜索新段;flush 将段持久化落盘并清空 translog。不可变段 + 删除标记实现更新,避免原地修改的并发锁与磁盘碎片。
5.2 段合并策略
随时间累积大量小段,后台采用分层合并(Tiered Merge)按规模分级合并,减少段数、提升检索与稳定性。合并触发条件通常包括:段数量达到阈值、删除文档占比超过阈值、或某段过大。合并瞬时会产生额外 I/O,生产常结合索引生命周期(ILM)与滚动索引错峰处理。
5.3 主分片与副本的一致性
写入由主分片负责并同步到副本;检索默认在主、副本间负载均衡。通过 wait_for_active_shards 可控制至少多少活跃副本确认写入,在可用性与一致性之间权衡。
六、聚合分析与本篇小结
6.1 三类聚合
ES 内置三类聚合支撑实时分析:
类别 | 代表 | 用途 |
指标 Metric | avg / sum / max / percentiles | 数值统计 |
桶 Bucket | terms / date_histogram / range | 分组与时间分桶 |
管道 Pipeline | bucket_script / derivative | 基于聚合再加工 |
6.2 本篇小结
本讲厘清 ES 内核四块基石:倒排索引以「词项→文档」映射换来毫秒级检索;分词器与映射决定文本如何被拆解与检索;BM25 在词频与文档长度间平衡出相关性排序;近实时刷新与分层段合并支撑高效写入。理解这些原理,是后续部署、选型与调优的基础。
下一篇进入部署实操,在内网环境落地 Elasticsearch 集群(含高可用与一键脚本)。