核心概念
写入es(此时生成倒排索引),分词器,分词(词项/词典),倒排索引(包含词典和倒排列表),
词项与稳定映射(俗称倒排列表),词项:文档ID:在文档中出现的位置和频率
Elasticsearch(ES)倒排索引原理是其核心的搜索和查询效率基础。倒排索引是一种数据结构,用于快速查找包含特定词项的文档。在 Elasticsearch 中,倒排索引是用来加速搜索的主要方式。
1. 倒排索引基本概念
倒排索引的基本思想是:对于每个词项(term),记录它在哪些文档中出现过,并且记录它在这些文档中的位置。倒排索引通常由两个主要部分组成:
- 词典(Dictionary):包含所有出现过的词项(term)。
- 倒排列表(Posting list):每个词项对应的文档ID列表,表示哪些文档包含该词项。它通常还包含该词项在文档中的位置或频率等信息。
2. 倒排索引构建过程
构建倒排索引的过程一般包括以下几个步骤:
-
文档解析: Elasticsearch 将文档分词。文档中的每个字段(如标题、正文)都会经过分析器(Analyzer)分词,得到一系列的词项(term)。比如,“The quick brown fox” 会被分词成:["the", "quick", "brown", "fox"]。
-
词项标准化: Elasticsearch 在分词时,会对每个词项进行标准化处理,例如转换为小写、去除停用词(如“the”、“a”等)、词干提取(如将“running”转为“run”)等。
-
生成倒排索引:
- 对于每个词项,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. 倒排索引的查询过程
倒排索引的查询过程通常如下:
-
查询解析:用户发起的查询会被解析成一系列的词项。例如,查询
quick fox
会被解析为包含quick
和fox
的查询。 - 查找倒排索引:查询系统会根据每个词项在倒排索引中的位置,快速找到包含该词项的文档ID。
- 合并结果:系统将所有词项的倒排列表合并,得到包含所有词项的文档集合(交集查询)。如果是布尔查询(OR、AND),则会进行不同的集合操作。
- 评分和排序:最后,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 时,一般的工作流程是:
- 客户端发送请求:客户端(如应用程序、Logstash 等)发送一个 HTTP 请求,包含要写入的文档。
- 分片选择:Elasticsearch 根据索引的分片策略决定将数据写入哪个分片。
- 文档分析和分词:文档的字段会使用定义的分析器进行分词,生成一个或多个词项(tokens)。
- 创建倒排索引:生成倒排索引并将文档ID及词项的映射存储到倒排索引中。
- 写入存储:倒排索引被写入到 Elasticsearch 的内部存储中,并对用户提供查询服务。
5. 总结
倒排索引的构建是在数据写入到 Elasticsearch 时进行的。每当文档被添加、更新或删除时,Elasticsearch 会根据文档的内容构建或更新相应的倒排索引。这使得 Elasticsearch 能够快速响应基于词项的查询,而不是在查询时才进行倒排索引的生成。
在实际使用中,Elasticsearch 会通过实时索引的方式在写入时完成倒排索引的生成,这样可以确保查询时总是能够基于最新的索引来执行。