Elasticsearch查询流程
Elasticsearch 的查询过程涉及多个关键数据结构,其中 Term Index 和 Posting List 是倒排索引(Inverted Index)的核心组成部分。以下是详细流程及这些组件的具体作用:
1. 数据写入与索引构建
在查询之前,数据会通过以下步骤建立倒排索引:
- 文本分词:将文档内容按分词器(如
standard
、ik
)拆分为词项(Term)。 - 生成倒排索引:
- Term Dictionary:存储所有唯一词项(如 “apple”、”banana”),按字典序排列。
- Term Index:基于 FST(Finite State Transducer)的词项索引,用于快速定位 Term 在 Term Dictionary 中的位置。
- Posting List:记录每个 Term 对应的文档列表(DocID)、词频(TF)、位置(Position)等元数据。
2. 查询过程详解
以 Term Query(精确匹配词项)为例,查询流程如下:
(1) 解析查询请求
用户发起查询 GET /index/_search { "query": { "term": { "text": "apple" } } }
,Elasticsearch 解析请求,确定目标字段(text
)和查询词项(apple
)。
(2) 定位 Term
- Term Index(FST):
- 在内存中快速匹配词项前缀,缩小查找范围。
- 例如:查找 “apple” 时,FST 跳过不相关前缀(如 “appl” 之前的项),定位到 “apple” 在 Term Dictionary 中的大致位置。
- Term Dictionary:
- 基于 FST 的定位结果,从磁盘或内存中检索完整词项 “apple”。
(3) 获取 Posting List
- Posting List 结构:
- DocIDs:包含 “apple” 的文档 ID 列表(如
[1, 3, 5]
)。 - 词频(TF):每个文档中 “apple” 出现的次数。
- 位置(Position):词项在文档中的具体位置(用于短语查询)。
- DocIDs:包含 “apple” 的文档 ID 列表(如
- 存储优化:
- 压缩算法:如 Frame Of Reference(FOR)或 Roaring Bitmaps,减少存储空间。
- 分块存储:Posting List 按块划分,支持快速跳跃遍历。
(4) 合并 Posting List(复杂查询)
对于组合查询(如 "apple AND banana"
):
分别获取 “apple” 和 “banana” 的 Posting List。
合并操作:
- 交集(AND):使用跳表(Skip List)或位图(Bitmap)快速找到共同 DocID。
- 并集(OR):合并去重 DocID。
1
2
3
4
5
6
7
8
9
10
11// 伪代码示例:跳表交集合并
while (cursor1 < list1.size() && cursor2 < list2.size()) {
if (list1[cursor1] == list2[cursor2]) {
result.add(list1[cursor1]);
cursor1++; cursor2++;
} else if (list1[cursor1] < list2[cursor2]) {
cursor1 = skipTo(cursor1, list2[cursor2]);
} else {
cursor2 = skipTo(cursor2, list1[cursor1]);
}
}
(5) 相关性评分与排序
评分模型:使用 BM25 或 TF-IDF 计算文档相关性得分。
1
2# BM25 公式简化版
score = IDF * (TF * (k1 + 1)) / (TF + k1 * (1 - b + b * (doc_length / avg_doc_length)))排序:按得分降序排列 DocID,筛选 Top N 结果。
(6) 获取文档内容
根据排序后的 DocID,从正排索引(行式存储的 _source
)中提取完整文档内容并返回。
3. 关键优化技术
组件 | 优化手段 | 目的 |
---|---|---|
Term Index | FST 压缩算法 | 减少内存占用,加快前缀匹配速度 |
Posting List | Roaring Bitmaps + 分块压缩 | 高效存储和合并大规模 DocID 集合 |
查询合并 | 跳表(Skip List)位图运算 | 加速 AND/OR 逻辑操作 |
评分缓存 | 缓存频繁查询的评分结果 | 减少重复计算,提升响应速度 |
4. 示例:短语查询(Phrase Query)
查询 "quick brown fox"
时:
- 分别获取 “quick”、”brown”、”fox” 的 Posting List。
- 检查它们在文档中的位置是否连续(如
quick@pos=1, brown@pos=2, fox@pos=3
)。 - 合并满足连续位置的 DocID,生成最终结果。
总结
- Term Index:内存中的前缀索引,用于快速定位词项,减少磁盘访问。
- Posting List:存储词项的文档分布信息,支持高效合并和评分。
- 性能核心:通过 FST、压缩算法和合并优化,Elasticsearch 能在毫秒级处理海量数据查询。
Elasticsearch查询流程
http://example.com/2025/05/25/es查询流程_副本/