Elasticsearch查询优化:理解Search的Query-Then-Fetch策略与相关性算分

0 下载量 140 浏览量 更新于2024-08-30 收藏 928KB PDF 举报
在深入理解Elasticsearch搜索的运行机制时,我们首先要了解搜索过程分为两个关键阶段:Query阶段和Fetch阶段。这两个阶段构成了Query-Then-Fetch的基本工作流程。 Query阶段是搜索过程的初始步骤,它负责解析和执行用户的查询请求,包括语法解析、查询条件的处理以及构建查询计划。在这个阶段,Elasticsearch会对查询进行优化,如词法分析、解析查询语法、构建查询树等,以便有效地找到相关的文档。 Fetch阶段则是在Query阶段筛选出候选文档后,进一步从每个Shard中实际读取数据。在这个阶段,每个Shard独立计算文档的相关性得分,但存在一个问题:由于IDF值(逆文档频率)在不同Shard上可能不一致,当文档量较少时,可能导致相关性得分不准确。这可能导致搜索结果偏离预期,尤其是在百万到千万级别文档量的场景下。 解决这个问题有两种策略: 1. 设置单个分片:当文档量较小,为了确保相关性得分的一致性,可以将分片数设为1,这样可以避免跨Shard的相关性差异。然而,这将牺牲水平扩展能力,并可能在高并发情况下性能下降。 2. 使用DFS Query-then-Fetch:这是一种特殊的查询方式,它会在所有文档被收集后,在内存中重新计算整个文档集合的相关性得分。这种方法虽然可以提供更准确的结果,但代价是消耗大量的CPU和内存资源,导致性能较低,因此在大多数情况下并不推荐使用。用户可以自定义排序规则,例如针对text和keyword类型的排序,其中text类型排序依赖于正排索引,而keyword类型则可以直接利用存储的原始值。 Elasticsearch提供了三种排序实现方式:默认的排序基于相关性得分,但用户可以调整;`fielddata`允许按分词后的term排序,适用于聚合分析;`docvalues`是默认启用的,提供更快的排序速度,但文本类型除外。若需切换到`docvalues`,可能需要重新索引。通过这些选项,开发者可以根据具体需求选择最合适的排序策略来优化搜索性能和结果质量。