参考答案:
Elasticsearch 是一个基于 Lucene 构建的分布式搜索引擎,它的核心功能之一就是快速的索引和搜索功能。在 Elasticsearch 中,索引 文档的过程是一个多步骤的流程,涉及到文档的处理、存储、分片分配以及倒排索引的构建等。以下是详细描述 Elasticsearch 索引文档的过程:
当客户端向 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
作为通用类型。1
):指定文档的唯一标识符。Elasticsearch 使用路由机制将文档路由到某个特定的分片。分片是 Elasticsearch 中数据的基本存储单位,每个索引会被分为多个分片。在 Elasticsearch 中,文档是基于其 _id
(文档 ID)进行路由的,默认情况下,文档 ID 会通过哈希算法决定它存储在哪个分片上。
_id
,Elasticsearch 会计算出该文档属于哪个分片。计算过程是将 _id
进行哈希,得到一个分片编号。例如,假设一个索引有 5 个分片,文档的 _id
会通过哈希算法映射到一个分片编号(0-4)。在文档被索引之前,Elasticsearch 会根据索引的 映射(Mapping) 来解析文档的字段。映射类似于数据库中的表结构,定义了每个字段的数据类型(如 text
、keyword
、date
、integer
等),以及其他的一些字段属性(如是否索引、是否存储等)。
例如,下面是一个简单的映射定义:
1PUT /my_index 2{ 3 "mappings": { 4 "_doc": { 5 "properties": { 6 "title": { "type": "text" }, 7 "content": { "type": "text" } 8 } 9 } 10 } 11}
如果没有明确指定映射,Elasticsearch 会根据文档的内容自动推断字段类型,这个过程叫做 动态映射。
对于字段类型为 text
的数据,Elasticsearch 会对其进行分词处理。分词器会将文本拆分成一系列的词项(tokens),这些词项会被存储在倒排索引中,以便进行快速查询。文本分析的过程包括以下几个步骤:
例如,文本 "Elasticsearch is a powerful search engine"
,通过分析器处理后,可能会被拆分为 ["elasticsearch", "powerful", "search", "engine"]
。
"store"
属性为 true
,字段的原始值会被存储在索引的存储文件中。通常情况下,只有需要返回给客户端的字段(如 title
和 content
)会被存储。当文档被解析和分析后,Elasticsearch 会根据文档的内容构建倒排索引。倒排索引是为了提高查询效率而设计的索引结构,它记录了每个词项出现在哪些文档中。在 Elasticsearch 中,倒排索引的构建过程包括:
例如,对于以下文档:
倒排索引可能如下:
Term | Doc ID(s) |
---|---|
elasticsearch | 1 |
is | 1, 2 |
search | 1, 2 |
engine | 1, 2 |
powerful | 2 |
在 Elasticsearch 中,索引的每个分片都是一个独立的 Lucene 索引实例。每个文档会根据 _id
被路由到特定的分片,在该分片上构建倒排索引。为了实现高可用性和数据冗余,Elasticsearch 会将每个分片复制为多个副本(replicas)。副本分片存储着与主分片相同的数据,并且可以用于查询请求。
每个分片的存储包括:
_id
、_version
、_score
等信息。当文档被成功处理、索引和存储后,它就被认为是被成功“索引”了。此时,文档已经被存储到对应的分片中,并且倒排索引已经构建完毕,能够支持快速的搜索操作。
为了提升存储效率和查询性能,Elasticsearch 定期会执行 合并操作(merge),将多个小的 Lucene 索引文件合并为一个大的索引文件。这可以减少文件碎片,并优化搜索性能。
最近更新时间:2024-12-12