Elasticsearch查询流程

Elasticsearch 的查询过程涉及多个关键数据结构,其中 Term IndexPosting List 是倒排索引(Inverted Index)的核心组成部分。以下是详细流程及这些组件的具体作用:


1. 数据写入与索引构建

在查询之前,数据会通过以下步骤建立倒排索引:

  1. 文本分词:将文档内容按分词器(如 standardik)拆分为词项(Term)。
  2. 生成倒排索引
    • 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):词项在文档中的具体位置(用于短语查询)。
  • 存储优化
    • 压缩算法:如 Frame Of Reference(FOR)或 Roaring Bitmaps,减少存储空间。
    • 分块存储:Posting List 按块划分,支持快速跳跃遍历。
(4) 合并 Posting List(复杂查询)

对于组合查询(如 "apple AND banana"):

  1. 分别获取 “apple” 和 “banana” 的 Posting List。

  2. 合并操作

    • 交集(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" 时:

  1. 分别获取 “quick”、”brown”、”fox” 的 Posting List。
  2. 检查它们在文档中的位置是否连续(如 quick@pos=1, brown@pos=2, fox@pos=3)。
  3. 合并满足连续位置的 DocID,生成最终结果。

总结
  • Term Index:内存中的前缀索引,用于快速定位词项,减少磁盘访问。
  • Posting List:存储词项的文档分布信息,支持高效合并和评分。
  • 性能核心:通过 FST、压缩算法和合并优化,Elasticsearch 能在毫秒级处理海量数据查询。

Elasticsearch查询流程
http://example.com/2025/05/25/es查询流程_副本/
Author
Lin
Posted on
May 25, 2025
Licensed under