问答题831/1053详细描述一下Elasticsearch索引文档的过程。

难度:
2021-11-02 创建

参考答案:

Elasticsearch 是一个基于 Lucene 构建的分布式搜索引擎,它的核心功能之一就是快速的索引和搜索功能。在 Elasticsearch 中,索引 文档的过程是一个多步骤的流程,涉及到文档的处理、存储、分片分配以及倒排索引的构建等。以下是详细描述 Elasticsearch 索引文档的过程:

1. 客户端请求和路由

1.1 文档的接收

当客户端向 Elasticsearch 发送请求时,它会请求索引一个文档。文档通常是一个 JSON 格式的数据,包含了要存储的数据及其字段。例如:

1POST /my_index/_doc/1 2{ 3 "title": "Elasticsearch Introduction", 4 "content": "Elasticsearch is a powerful search engine." 5}

这个请求的结构包括:

  • 索引名my_index):指定要索引的目标索引。
  • 文档类型_doc):指定文档类型,通常在现代 Elasticsearch 版本中使用 _doc 作为通用类型。
  • 文档 ID1):指定文档的唯一标识符。
  • 文档内容:需要存储的数据。

1.2 文档路由

Elasticsearch 使用路由机制将文档路由到某个特定的分片。分片是 Elasticsearch 中数据的基本存储单位,每个索引会被分为多个分片。在 Elasticsearch 中,文档是基于其 _id(文档 ID)进行路由的,默认情况下,文档 ID 会通过哈希算法决定它存储在哪个分片上。

  • 路由机制:通过文档的 _id,Elasticsearch 会计算出该文档属于哪个分片。计算过程是将 _id 进行哈希,得到一个分片编号。例如,假设一个索引有 5 个分片,文档的 _id 会通过哈希算法映射到一个分片编号(0-4)。
  • 分片数量:分片的数量在创建索引时指定,通常可以设置为 1 到 N 之间的数值。每个分片是一个独立的 Lucene 索引实例,负责存储文档和提供查询功能。

2. 文档解析和分析

2.1 文档结构和映射

在文档被索引之前,Elasticsearch 会根据索引的 映射(Mapping) 来解析文档的字段。映射类似于数据库中的表结构,定义了每个字段的数据类型(如 textkeyworddateinteger 等),以及其他的一些字段属性(如是否索引、是否存储等)。

例如,下面是一个简单的映射定义:

1PUT /my_index 2{ 3 "mappings": { 4 "_doc": { 5 "properties": { 6 "title": { "type": "text" }, 7 "content": { "type": "text" } 8 } 9 } 10 } 11}

如果没有明确指定映射,Elasticsearch 会根据文档的内容自动推断字段类型,这个过程叫做 动态映射

2.2 文本分析器(Analyzer)

对于字段类型为 text 的数据,Elasticsearch 会对其进行分词处理。分词器会将文本拆分成一系列的词项(tokens),这些词项会被存储在倒排索引中,以便进行快速查询。文本分析的过程包括以下几个步骤:

  1. 字符过滤(Character Filters):将输入文本进行预处理,例如去除 HTML 标签或其他无关字符。
  2. 分词(Tokenization):使用分词器将文本拆分成一个个单独的词项。
  3. 词项过滤(Token Filters):对分词后的词项进行处理,例如去除停用词(如 "and", "the" 等)、词干提取(例如将 “running” 转换为 “run”)等。

例如,文本 "Elasticsearch is a powerful search engine",通过分析器处理后,可能会被拆分为 ["elasticsearch", "powerful", "search", "engine"]

2.3 字段存储和索引

  • 存储字段:Elasticsearch 会根据字段的映射决定是否将字段存储到磁盘。如果字段的 "store" 属性为 true,字段的原始值会被存储在索引的存储文件中。通常情况下,只有需要返回给客户端的字段(如 titlecontent)会被存储。
  • 索引字段:每个字段的数据会被索引,以便可以高效地进行检索。对于文本字段,Elasticsearch 会通过分词器生成倒排索引,对于其他数据类型(如整数、日期等),则会生成倒排索引或其他适合的索引结构。

3. 文档索引和存储

3.1 倒排索引的构建

当文档被解析和分析后,Elasticsearch 会根据文档的内容构建倒排索引。倒排索引是为了提高查询效率而设计的索引结构,它记录了每个词项出现在哪些文档中。在 Elasticsearch 中,倒排索引的构建过程包括:

  1. 词项的生成:通过文本分析器对字段进行分词处理,生成词项(tokens)。
  2. 倒排索引的构建:为每个词项建立一个倒排索引,记录该词项在哪些文档中出现,并且记录它在文档中的位置。这使得 Elasticsearch 能够在查询时迅速找到相关文档。

例如,对于以下文档:

  • 文档 1: "Elasticsearch is a search engine"
  • 文档 2: "Search engine is powerful"

倒排索引可能如下:

TermDoc ID(s)
elasticsearch1
is1, 2
search1, 2
engine1, 2
powerful2

3.2 分片和副本的存储

在 Elasticsearch 中,索引的每个分片都是一个独立的 Lucene 索引实例。每个文档会根据 _id 被路由到特定的分片,在该分片上构建倒排索引。为了实现高可用性和数据冗余,Elasticsearch 会将每个分片复制为多个副本(replicas)。副本分片存储着与主分片相同的数据,并且可以用于查询请求。

每个分片的存储包括:

  • 倒排索引文件:包含了所有索引的词项和文档位置信息。
  • 存储字段数据:包含了文档字段的原始值(如果设置了存储)。
  • 文档的元数据:包括 _id_version_score 等信息。

4. 文档索引完成

当文档被成功处理、索引和存储后,它就被认为是被成功“索引”了。此时,文档已经被存储到对应的分片中,并且倒排索引已经构建完毕,能够支持快速的搜索操作。

5. 索引的优化

为了提升存储效率和查询性能,Elasticsearch 定期会执行 合并操作(merge),将多个小的 Lucene 索引文件合并为一个大的索引文件。这可以减少文件碎片,并优化搜索性能。

最近更新时间:2024-12-12