ES倒排索引

时间:2024-12-20 07:22:14

核心概念

写入es(此时生成倒排索引),分词器,分词(词项/词典),倒排索引(包含词典和倒排列表),

词项与稳定映射(俗称倒排列表),词项:文档ID:在文档中出现的位置和频率

Elasticsearch(ES)倒排索引原理是其核心的搜索和查询效率基础。倒排索引是一种数据结构,用于快速查找包含特定词项的文档。在 Elasticsearch 中,倒排索引是用来加速搜索的主要方式。

1. 倒排索引基本概念

倒排索引的基本思想是:对于每个词项(term),记录它在哪些文档中出现过,并且记录它在这些文档中的位置。倒排索引通常由两个主要部分组成:

  • 词典(Dictionary):包含所有出现过的词项(term)。
  • 倒排列表(Posting list):每个词项对应的文档ID列表,表示哪些文档包含该词项。它通常还包含该词项在文档中的位置或频率等信息。

2. 倒排索引构建过程

构建倒排索引的过程一般包括以下几个步骤:

  1. 文档解析: Elasticsearch 将文档分词。文档中的每个字段(如标题、正文)都会经过分析器(Analyzer)分词,得到一系列的词项(term)。比如,“The quick brown fox” 会被分词成:["the", "quick", "brown", "fox"]。

  2. 词项标准化: Elasticsearch 在分词时,会对每个词项进行标准化处理,例如转换为小写、去除停用词(如“the”、“a”等)、词干提取(如将“running”转为“run”)等。

  3. 生成倒排索引

    • 对于每个词项,Elasticsearch 会记录包含该词项的文档ID,称为倒排列表(posting list)。
    • 如果一个文档包含多个相同的词项,Elasticsearch 还会记录该词项在文档中的频率和位置,帮助后续查询优化

    例如,对于文档集合:

    json

    [ { "id": 1, "content": "quick brown fox" }, { "id": 2, "content": "lazy dog" }, { "id": 3, "content": "quick fox jumps" } ]

    分词后的内容为:

    • 文档 1: ["quick", "brown", "fox"]
    • 文档 2: ["lazy", "dog"]
    • 文档 3: ["quick", "fox", "jumps"]

    倒排索引的结果是:

    • quick → 文档 ID: [1, 3]
    • brown → 文档 ID: [1]
    • fox → 文档 ID: [1, 3]
    • lazy → 文档 ID: [2]
    • dog → 文档 ID: [2]
    • jumps → 文档 ID: [3]

3. 倒排索引的结构

倒排索引包含两个主要部分:

  • 词典(Dictionary):存储所有独特的词项。
  • 倒排列表(Posting List):存储每个词项的文档ID(以及其他信息,如位置、频率等)。

具体来说,倒排索引结构通常包括:

  • 词项(term):是搜索的基本单位,例如“quick”。
  • 文档ID(doc ID):该词项出现的文档的唯一标识。
  • 词项的频率(term frequency, TF):该词项在文档中出现的次数。
  • 词项的位置(term position):该词项在文档中的位置(如偏移量)。

4. 倒排索引的查询过程

倒排索引的查询过程通常如下:

  1. 查询解析用户发起的查询会被解析成一系列的词项。例如,查询 quick fox 会被解析为包含 quick 和 fox 的查询。
  2. 查找倒排索引查询系统会根据每个词项在倒排索引中的位置,快速找到包含该词项的文档ID。
  3. 合并结果:系统将所有词项的倒排列表合并,得到包含所有词项的文档集合(交集查询)。如果是布尔查询(OR、AND),则会进行不同的集合操作。
  4. 评分和排序:最后,Elasticsearch 会根据相关性算法(如 TF-IDF 或 BM25)对这些文档进行排序,返回最相关的文档。

5. 倒排索引的优缺点

优点

  • 查询速度快:倒排索引可以在O(log N)时间内快速找到包含某个词项的所有文档。相比于线性扫描文档,倒排索引的查询速度要快得多。
  • 适用于文本搜索:倒排索引非常适合于全文搜索,尤其是文本中的词项查询。

缺点

  • 索引空间开销大:对于大规模数据,倒排索引会占用较大的存储空间,因为需要为每个词项保存大量的信息。
  • 索引更新慢:倒排索引的更新比较复杂,尤其是在数据频繁更新的情况下,可能需要重新构建索引。

6. 优化与改进

Elasticsearch 在倒排索引的基础上做了很多优化,例如:

  • Doc values:为每个文档的字段值建立一种高效的存储结构,支持快速排序和聚合。
  • 反向文档频率(IDF):通过统计词项在文档中的出现频率,优化搜索相关性。
  • 分片和副本:为了支持高可用性和横向扩展,Elasticsearch 会将倒排索引分片,每个分片可以有多个副本。

总结

倒排索引是 Elasticsearch 中非常重要的一个概念,它通过记录每个词项对应的文档ID和相关信息,极大提高了文本搜索的效率。通过倒排索引,Elasticsearch 能够快速定位到包含特定词项的文档,并进行高效的查询和排序操作。

倒排索引什么时候进行的,数据写入esb时吗

在 Elasticsearch 中,倒排索引的构建通常是在数据 写入 Elasticsearch 时进行的,而不是在查询时进行的。具体来说,倒排索引的创建过程通常发生在以下几个阶段:

1. 数据写入时(索引过程)

当你将数据(文档)写入到 Elasticsearch 时,Elasticsearch 会对这些文档进行分析和索引。这个过程包括以下几个步骤:

  • 文档接收:Elasticsearch 会接收并存储你提交的文档。文档通常以 JSON 格式提交到特定的索引和类型中。
  • 分词和分析:每个字段会经过一个或多个分析器(Analyzer)进行分词,生成一系列的词项(tokens)。分析器会执行包括分词、词干化、去除停用词等操作。
  • 生成倒排索引:在分词的基础上,Elasticsearch 会为每个词项生成倒排索引。这意味着 Elasticsearch 会记录哪些文档包含该词项,并建立词项到文档的映射(即倒排列表)。这个过程发生在数据写入时,而不是查询时。

2. 倒排索引的细节

  • 字段映射(Mapping):在创建索引时,你通常会定义一个映射(mapping),指定哪些字段需要建立倒排索引(如文本字段)。某些字段(如数字、日期类型)可能不需要倒排索引,而是直接存储在字段数据结构中。
  • 实时索引:Elasticsearch 会将数据实时索引,这意味着数据写入之后,倒排索引会立即更新,以便后续的搜索请求可以使用最新的数据。虽然 Elasticsearch 使用了分布式的设计,但每个文档都在局部节点进行索引和写入。

3. 索引更新

  • 新文档:对于新文档,Elasticsearch 会直接为其创建新的倒排索引并添加到现有的倒排索引结构中。
  • 更新文档:当文档被更新时,Elasticsearch 会删除旧文档的倒排索引并为更新后的文档重新生成倒排索引。需要注意的是,Elasticsearch 并不会直接修改原有的索引,而是通过删除并重新创建索引来更新倒排索引。

4. 数据写入到 ES 集群时的工作流

当数据写入到 Elasticsearch 时,一般的工作流程是:

  1. 客户端发送请求:客户端(如应用程序、Logstash 等)发送一个 HTTP 请求,包含要写入的文档。
  2. 分片选择:Elasticsearch 根据索引的分片策略决定将数据写入哪个分片。
  3. 文档分析和分词:文档的字段会使用定义的分析器进行分词,生成一个或多个词项(tokens)。
  4. 创建倒排索引:生成倒排索引并将文档ID及词项的映射存储到倒排索引中。
  5. 写入存储:倒排索引被写入到 Elasticsearch 的内部存储中,并对用户提供查询服务。

5. 总结

倒排索引的构建是在数据写入到 Elasticsearch 时进行的。每当文档被添加、更新或删除时,Elasticsearch 会根据文档的内容构建或更新相应的倒排索引。这使得 Elasticsearch 能够快速响应基于词项的查询,而不是在查询时才进行倒排索引的生成。

在实际使用中,Elasticsearch 会通过实时索引的方式在写入时完成倒排索引的生成,这样可以确保查询时总是能够基于最新的索引来执行。