Elasticsearch搜索类型(query type)详解

本文深入解析了Elasticsearch在分布式搜索环境下,四种查询类型的区别与应用场景,包括QUERY_AND_FETCH、QUERY_THEN_FETCH、DFS_QUERY_AND_FETCH与DFS_QUERY_THEN_FETCH。详细阐述了每种查询方式的工作原理、性能考量及搜索准确性,帮助开发者根据需求选择最适合的查询策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

es在查询时,可以指定搜索类型为QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH。那么这4种搜索类型有什么区别?
 
分布式搜索背景介绍:
ES天生就是为分布式而生,但分布式有分布式的缺点。比如要搜索某个单词,但是数据却分别在5个分片(Shard)上面,这5个分片可能在5台主机上面。因为全文搜索天生就要排序(按照匹配度进行排名),但数据却在5个分片上,如何得到最后正确的排序呢?ES是这样做的,大概分两步。
step1、ES客户端会将这个搜索词同时向5个分片发起搜索请求,这叫Scatter,
step2、这5个分片基于本Shard独立完成搜索,然后将符合条件的结果全部返回,这一步叫Gather。
客户端将返回的结果进行重新排序和排名,最后返回给用户。也就是说,ES的一次搜索,是一次scatter/gather过程(这个跟mapreduce也很类似).
 
然而这其中有两个问题。
第一、数量问题。比如,用户需要搜索"双黄连",要求返回最符合条件的前10条。但在5个分片中,可能都存储着双黄连相关的数据。所以ES会向这5个分片都发出查询请求,并且要求每个分片都返回符合条件的10条记录。当ES得到返回的结果后,进行整体排序,然后取最符合条件的前10条返给用户。这种情况,ES5个shard最多会收到10*5=50条记录,这样返回给用户的结果数量会多于用户请求的数量。
第二、排名问题。上面搜索,每个分片计算分值都是基于自己的分片数据进行计算的。计算分值使用的词频率和其他信息都是基于自己的分片进行的,而ES进行整体排名是基于每个分片计算后的分值进行排序的,这就可能会导致排名不准确的问题。如果我们想更精确的控制排序,应该先将计算排序和排名相关的信息(词频率等)从5个分片收集上来,进行统一计算,然后使用整体的词频率去每个分片进行查询。
 
这两个问题,估计ES也没有什么较好的解决方法,最终把选择的权利交给用户,方法就是在搜索的时候指定query type。
1、query and fetch
向索引的所有分片(shard)都发出查询请求,各分片返回的时候把元素文档(document)和计算后的排名信息一起返回。这种搜索方式是最快的。因为相比下面的几种搜索方式,这种查询方法只需要去shard查询一次。但是各个shard返回的结果的数量之和可能是用户要求的size的n倍。
2、query then fetch(默认的搜索方式)
如果你搜索时,没有指定搜索方式,就是使用的这种搜索方式。这种搜索方式,大概分两个步骤,第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。这种方式返回的document与用户要求的size是相等的。
3、DFS query and fetch
这种方式比第一种方式多了一个初始化散发(initial scatter)步骤,有这一步,据说可以更精确控制搜索打分和排名。
4、DFS query then fetch
比第2方式多了一个初始化散发(initial scatter)步骤。
 
DSF是什么缩写?初始化散发是一个什么样的过程?
从es的官方网站我们可以指定,初始化散发其实就是在进行真正的查询之前,先把各个分片的词频率和文档频率收集一下,然后进行词搜索的时候,各分片依据全局的词频率和文档频率进行搜索和排名。显然如果使用DFS_QUERY_THEN_FETCH这种查询方式,效率是最低的,因为一个搜索,可能要请求3次分片。但,使用DFS方法,搜索精度应该是最高的。
至于DFS是什么缩写,没有找到相关资料,这个D可能是Distributed,F可能是frequency的缩写,至于S可能是Scatter的缩写,整个单词可能是分布式词频率和文档频率散发的缩写。
总结一下,从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高。
<think>嗯,用户问的是Elasticsearch中的multi_match查询,需要详细解释。首先,我得回顾一下multi_match的基本概念和用途。multi_match是用于在多个字段中执行相同的查询,可以替代多个match查询的组合,简化查询语句。这点我记得没错。 接下来,需要介绍它的基本语法结构。用户可能想知道怎么写一个multi_match查询,包括查询字符串、字段列表以及可选的类型参数。例如,用"query"指定搜索内容,"fields"列出字段,可能还要提到通配符的使用,比如title和content的加权,比如title^3。 然后,要讲解不同的类型type参数)。这里可能需要详细说明每种类型的适用场景,比如best_fields、most_fields、cross_fields、phrase、phrase_prefix以及bool_prefix。比如best_fields是默认的,找任一字段最佳匹配,使用dis_max;most_fields则是合并多个字段的评分;cross_fields处理跨字段的情况,比如姓名分开存储时的查询。 还要提到每种类型的内部实现机制,比如best_fields对应dis_max查询,most_fields使用bool查询的should子句组合。cross_fields如何将查询条件拆分到不同字段,以及它们的评分方式差异。 然后,可能需要举例说明不同场景下的应用。比如,在电商搜索中,商品名称和描述字段使用best_fields,而跨字段如姓名分开存储时用cross_fields。还要说明不同查询类型对评分的影响,以及如何影响搜索结果排序。 用户可能还想知道如何选择正确的类型,这部分需要给出一些指导原则,比如字段内容相似用best_fields,不同用most_fields,需要跨字段匹配用cross_fields等。同时,注意事项比如通配符字段的性能问题,避免过多字段,以及不同类型对评分的影响。 需要检查是否有遗漏的重要点,比如模糊匹配、运算符设置(and/or),或者与multi_match相关的其他参数,比如analyzer、boost等。可能还要提到版本差异,确保用户使用的Elasticsearch版本支持提到的类型。 最后,总结一下multi_match的优势,比如简化多字段查询,灵活性高,支持不同策略。同时提醒用户根据实际需求调整类型和参数,结合测试优化查询效果。确保语言通俗易懂,结构清晰,分点说明,让用户能够一步步理解multi_match的用法和应用场景。</think>Elasticsearch 的 `multi_match` 查询是用于在多个字段中执行相同搜索条件的查询,是 `match` 查询的多字段扩展版本。以下是详细说明: --- ### **一、基础语法** ```json { "query": { "multi_match": { "query": "搜索关键词", "fields": ["字段1", "字段2^3", "wildcard字段*"], "type": "best_fields" } } } ``` - **query**: 要搜索的文本内容。 - **fields**: 指定搜索的字段列表,支持通配符(如 `title.*`)。 - 字段加权:通过 `^` 符号提升字段权重(例如 `title^3` 表示 `title` 字段权重是默认的 3 倍)。 - **type**: 指定匹配策略(核心参数,下文详解)。 --- ### **二、type 类型详解** #### 1. **best_fields(默认值)** - **用途**:在任一字段中找到最佳匹配的文档(类似 `OR` 逻辑)。 - **原理**:内部使用 `dis_max` 查询,取所有字段中的最高评分。 - **适用场景**:字段内容高度相似(例如 `title` 和 `description`)。 - **可选参数**: - `tie_breaker`:为其他字段的匹配评分添加权重(0~1),默认 0。 #### 2. **most_fields** - **用途**:合并多个字段的匹配评分(类似 `OR` 叠加评分)。 - **原理**:内部使用 `bool` 查询的 `should` 子句组合多个 `match` 查询。 - **适用场景**:字段内容不同且需综合评分(例如不同语言的翻译字段)。 #### 3. **cross_fields** - **用途**:将搜索条件拆分成多个词项,跨字段匹配(类似“组合查询”)。 - **原理**:将查询词项分配到不同字段,要求所有词项都匹配(类似 `AND`)。 - **适用场景**:字段内容互补(例如 `first_name` 和 `last_name` 分开存储时搜索全名)。 #### 4. **phrase** - **用途**:精确匹配短语(类似 `match_phrase` 的多字段版本)。 - **原理**:在所有字段中搜索完整短语。 - **可选参数**: - `slop`:允许短语中词项的最大间隔(默认 0)。 #### 5. **phrase_prefix** - **用途**:支持最后一个词项的模糊匹配(类似 `match_phrase_prefix`)。 - **原理**:在所有字段中搜索短语前缀。 - **可选参数**: - `max_expansions`:限制最后一个词项的扩展数量(默认 50)。 #### 6. **bool_prefix** - **用途**:将查询拆分为词项,最后一个词项作为前缀匹配。 - **原理**:类似 `match_bool_prefix` 的多字段版本。 --- ### **三、典型场景示例** #### 场景 1:电商商品搜索 ```json { "query": { "multi_match": { "query": "无线蓝牙耳机", "fields": ["title^3", "description", "tags"], "type": "best_fields", "tie_breaker": 0.3 } } } ``` - **说明**:优先匹配 `title` 字段,同时兼顾 `description` 和 `tags` 字段。 #### 场景 2:跨字段姓名搜索 ```json { "query": { "multi_match": { "query": "张三 北京", "fields": ["first_name", "last_name", "address"], "type": "cross_fields", "operator": "and" } } } ``` - **说明**:要求“张三”和“北京”必须同时在任意字段组合中出现。 --- ### **四、注意事项** 1. **性能影响**: - 避免使用过多字段(尤其是通配符 `*`),可能降低查询速度。 - `phrase` 和 `phrase_prefix` 类型消耗资源较高。 2. **评分差异**: - `best_fields` 可能忽略其他字段的匹配信息,`most_fields` 会累加评分。 3. **字段分析器**: - 确保所有字段使用相同的分词器(否则 `cross_fields` 可能失效)。 --- ### **五、如何选择 type 类型?** | 场景特点 | 推荐类型 | |------------------------------|----------------| | 字段内容高度相似 | `best_fields` | | 字段内容差异大且需综合评分 | `most_fields` | | 需要跨字段组合匹配(如姓名) | `cross_fields` | | 精确短语匹配 | `phrase` | | 自动补全或前缀搜索 | `phrase_prefix` | --- 通过合理使用 `multi_match` 查询,可以灵活应对多字段搜索需求,但需根据数据特点选择匹配策略,并结合实际测试优化参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值