Elasticsearch 搜索过程详解
Elasticsearch 是一个基于 Lucene 的分布式搜索和分析引擎,广泛应用于全文搜索、日志分析和数据监控等场景。Elasticsearch 的搜索过程涉及多个步骤,从接收查询请求到返回搜索结果,每一步都对搜索性能和结果的相关性至关重要。
一、Elasticsearch 搜索的基本流程
Elasticsearch 的搜索过程可以分为以下几个主要步骤:
- 接收搜索请求:用户通过 RESTful API 向 Elasticsearch 发送搜索请求。
- 查询解析与分发:Elasticsearch 解析请求,将查询任务分发给相关的分片。
- 分片执行查询:每个分片在其本地数据副本上执行查询,并计算相关性得分。
- 结果合并与排序:节点收集各分片的结果,合并和排序后返回最终结果给用户。
每个步骤在 Elasticsearch 搜索过程中都起到了重要作用。接下来,我们将详细讲解每个步骤的具体内容和相关概念。
二、搜索请求的接收与解析
当用户向 Elasticsearch 发起搜索请求时,通常使用 RESTful API 通过 HTTP 协议发送查询语句。查询语句可以是简单的关键词搜索,也可以是复杂的多条件组合查询。
1. 查询请求的基本结构
一个典型的 Elasticsearch 查询请求包含以下部分:
- 请求方法:通常使用 HTTP 的
GET或POST方法。 - 索引名称:指定查询的目标索引。
- 查询体(Query DSL):查询的核心部分,使用 JSON 格式的 Elasticsearch 查询 DSL(Domain Specific Language)来描述查询条件。
例如,以下是一个简单的搜索请求,它在名为 my_index 的索引中查找包含词项 “Elasticsearch” 的文档:
GET /my_index/_search
{
"query": {
"match": {
"content": "Elasticsearch"
}
}
}
2. 查询解析
Elasticsearch 的接收节点(协调节点,Coordinating Node)会接收到用户的搜索请求,并将查询转换为 Elasticsearch 的内部查询表示。查询解析阶段的主要任务包括:
- 解析用户查询的 DSL 语句。
- 构建查询上下文,包括查询的索引、类型、字段、过滤条件等。
- 确定需要查询的分片。
三、查询任务的分发与执行
在查询解析完成后,协调节点将查询任务分发到集群中的相关分片。Elasticsearch 使用分布式架构,索引被划分为多个分片(Shard),每个分片是一个独立的 Lucene 索引。查询任务被并行地分发到多个分片上执行,以提高搜索性能。
1. 分片选择与查询分发
Elasticsearch 会根据索引的分片配置(主分片和副本分片)来选择合适的分片执行查询。对于每个主分片,查询可以发送到主分片或其副本分片之一,具体选择取决于分片的负载情况和可用性。这样可以平衡查询负载,提高集群性能。
例如,假设 my_index 索引有 5 个主分片,每个主分片有 1 个副本。查询请求可以在 10 个分片(5 个主分片和 5 个副本分片)中分发执行。
2. 分片上的查询执行
每个分片接收到查询请求后,会在其本地数据上执行查询。分片的查询过程包括以下步骤:
- 词项查询:对于全文搜索,首先需要在倒排索引上执行词项查询。倒排索引将词项映射到包含这些词项的文档列表,能够快速定位相关文档。
- 文档过滤:对查询中的过滤条件进行判断,例如数值范围过滤、地理位置过滤等。
- 相关性评分计算:使用 BM25 算法或其他计算模型,为每个符合查询条件的文档计算相关性得分。相关性评分越高,文档越符合用户的查询意图。
四、结果收集与合并
各个分片在本地执行查询后,将部分结果返回给协调节点。协调节点的任务是收集这些结果,进行合并和排序,并返回最终的结果给用户。
1. Top-K 结果收集
在大多数情况下,用户只需要最相关的前 K 条结果,而不是所有匹配的文档。因此,分片通常只返回前 K 条文档及其相关性得分。协调节点负责将来自不同分片的 Top-K 结果合并为全局 Top-K 结果。
2. 全局排序与分页
协调节点对收集到的结果进行全局排序,根据相关性得分或其他指定的排序规则进行排列。排序完成后,根据分页参数(如 from 和 size 参数)来确定最终返回给用户的结果。
例如,如果查询请求需要返回第 11 到 20 条结果,协调节点会先收集足够多的文档,进行全局排序后,截取第 11 到 20 条作为返回结果。
五、查询类型与优化
Elasticsearch 提供了多种查询类型和优化技术,以支持不同的应用场景和查询需求。
1. 查询类型
-
match查询:全文搜索的基本查询类型,用于查找与词项匹配的文档。match查询会对输入文本进行分词和分析。 -
term查询:精确值查询,查找包含指定词项的文档。通常用于结构化数据的查询,不会对输入值进行分词。 -
range查询:范围查询,适用于数值、日期或其他可排序数据类型的查询。 -
bool查询:布尔查询,允许使用多个子查询组合(如must、should、must_not)来构建复杂查询条件。 -
geo查询:地理空间查询,适用于地理位置数据的搜索和过滤。
2. 查询优化
Elasticsearch 通过多种方式优化查询性能,以下是一些常用的优化技术:
-
索引优化:索引优化包括分片合并(Segment Merging)和压缩索引(Index Compression)。合并和压缩能够减少查询的 I/O 操作,提高查询速度。
-
缓存:Elasticsearch 使用查询结果缓存和过滤器缓存来存储频繁查询的结果和过滤条件,减少重复计算,提升查询性能。
-
预过滤与惰性加载:对于复杂的布尔查询,Elasticsearch 使用预过滤策略和惰性加载策略,以减少不必要的计算和数据加载,提升查询效率。
-
Scroll 和 Search After:对于需要处理大量结果的查询,可以使用 Scroll API 或
search_after参数来逐步获取结果,避免一次性加载大量数据,减少内存占用。
六、相关性评分与 BM25 算法
在搜索结果中,Elasticsearch 使用相关性评分来衡量每个文档与用户查询的匹配程度。BM25 是 Elasticsearch 默认的相关性评分算法,它是 TF-IDF(词频-逆文档频率)模型的改进版本。
1. BM25 相关性评分公式
BM25 评分公式如下:
[
\text{score}(q, d) = \sum_{t \in q} \text{IDF}(t) \cdot \frac{\text{TF}(t, d) \cdot (k_1 + 1)}{\text{TF}(t, d) + k_1 \cdot (1 - b + b \cdot \frac{|d|}{\text{avgdl}})}
]
其中:
- TF(t, d):词项
t在文档d中的词频。 - IDF(t):词项
t的逆文档频率。 - |d|:文档
d的长度(词项数量)。 - avgdl:所有文档的平均长度。
- k1 和 b:BM25 的调节参数,通常取
k1 = 1.2,b = 0.75。
BM25 根据词频、逆文档频率和文档长度进行平衡,能够更好地计算相关性得分。
七、总结
Elasticsearch 的搜索过程涉及多个步骤和组件,从接收用户的搜索请求,到解析、分发、执行查询,再到结果收集与排序,最后返回给用户。通过使用倒排索引、分布式查询、查询优化和相关性评分等技术,Elasticsearch 能够提供高效、快速和相关性高的搜索体验。
260

被折叠的 条评论
为什么被折叠?



