Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query

本文深入探讨Elasticsearch中的MatchPhraseQuery与MatchPhrasePrefixQuery,详细解析slop参数、analyzer参数及max_expansions的作用,通过实例演示如何进行精确短语匹配与前缀查询。

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

作者:ReyCG

出处:ReyCG 的博客 — https://www.cnblogs.com/reycg-blog/

Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query

引言

今天再读庄子的《逍遥游》,其中鲲鹏之扶摇直上九万里之气势,蜩(tiao)与学鸠之渺小之对比,令人印象深刻,并对鲲鹏之志心生向往。而郭象在注《庄子》卷中却说,"苟足于其性,则虽大鹏无以自贵于小鸟,小鸟无羡于天池,而荣愿有余矣。故小大虽殊,逍遥一也。"观看自身,虽然不是什么领导,老总,但也完全不必感到为职业生涯忧虑,只要热爱程序员这个工作,享受编码的乐趣,做到 80 岁又有何妨。

书归正传,今天我们聊聊 Match Phase Query。

Match Phase Query

match_phrase 查询针对的是一个语句,比如 "like football", 分析时也会将整个语句作为整体,而不会像上篇的 match 查询 会将整个语句拆分为单个词条。

举个例子,创建一个 match_phase type 并塞进去一个文档, message 是 I like swimming and riding!

PUT matchphasetest
{}

PUT matchphasetest/_mapping/match_phase
{
“properties”: {
“message”: {
“type”: “text”
}
}
}

PUT matchphasetest/match_phase/1
{
“message”: “I like swimming and riding!”
}

GET matchphasetest/_search
{
“query”: {
“match_phrase”: {
“message”: “I like swimming”
}
}
}

默认使用 match_phrase 时会精确匹配查询的短语,需要全部单词和顺序要完全一样,标点符号除外。

slop 参数

这种精确匹配在大部分情况下显得太严苛了,有时我们想要包含 ""I like swimming and riding!"" 的文档也能够匹配 "I like riding"。这时就要以用到 "slop" 参数来控制查询语句的灵活度。

slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配 什么是相隔多远? 意思是说为了让查询和文档匹配你需要移动词条多少次?

以 "I like swimming and riding!" 的文档为例,想匹配 "I like riding",只需要将 "riding" 词条向前移动两次,因此设置 slop 参数值为 2, 就可以匹配到。

GET matchphasetest/_search
{
  "query": {
    "match_phrase": {
      "message": {
        "query": "I like riding",
        "slop": 2
      }
    }
  }
}

analyzer 参数

match_phrase 语句也可以设置 analyzer 参数来定义查询语句时对其中词条执行的分析过程。

默认情况下,使用的是创建 mapping 时的分析器,如果没有指定就会使用默认的查询分析器。这里举个例子(只是如何使用)

GET /_search
{
    "query": {
        "match_phrase" : {
            "message" : {
                "query" : "this is a test",
                "analyzer" : "my_analyzer"
            }
        }
    }
}

zero terms query

match_phrase 也接受 zero_terms_query 为参数,使用方式和 match查询语句相同

Match Phrase 前缀查询

match_phrase_prefixmatch_phrase 用法是一样的,区别就在于它允许对最后一个词条前缀匹配。以上节的数据为例,查询 I like sw 就能匹配到

I like swimming and riding

GET matchphasetest/_search
{
  "query": {
    "match_phrase_prefix": {
      "message": "I like swi"
    }
  }
}

max_expansions

官方文档中说 match_phrase_prefix 查询中有个参数 max_expansions 说的是参数 max_expansions 控制着可以与前缀匹配的词的数量,默认值是 50。

I like swi 查询为例,它会先查找第一个与前缀 swi 匹配的词,然后依次查找搜集与之匹配的词(按字母顺序),直到没有更多可匹配的词或当数量超过 max_expansions 时结束。

但是我在使用时,故意造出了数十个以 swi 开头的词,而将 max_expansions 的值设为 10。但是却返回了所有的结果。在 elasitc 官网也有对该问题的讨论, 也是没有找到答案。这个问题作为一个公案权且记下,如果您知道原因,麻烦告诉我,非常感谢。

这里也贴出个例子,以备后面排查

GET matchphaseprefixtest/_search
{
  "query": {
    "match_phrase_prefix": {
      "message": {
        "query": "I like sw",
        "max_expansions": 10
       }
    }
  }
}

match_phrase_prefix 用起来非常方便,能够实现输入即搜索的效果,但是也会出现问题。 假如说查询 I like s 并且想要匹配 I like swimming ,结果是默认情况下它会搜索出前 50 个组合,如果前 50 个没有 swimming ,那就不会显示出结果。只能是用户继续输入后面的字母才可能匹配出结果。

要实现更好的即使搜索的特性,可以看看 completion suggester
Index-Time Search-as-You-Type 能不能实现。

小结

本文论述了 Match Phase Query 和 Match Phrase 前缀查询 的使用,下文会讲解 Multi Match Query 敬请期待。

参考文档

1.Match Phrase Query

系列文章列表

Query DSL

  1. Query DSL 概要,MatchAllQuery,全文查询简述
  2. Match Query

Java Rest Client API

  1. Elasticsearch Java Rest Client API 整理总结 (一)——Document API
  2. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
  3. Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
« 上一篇: Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了
» 下一篇: Elasticsearch 系列文章汇总(持续更新...)
<think>嗯,用户想了解Elasticsearch中的Match Query,我需要详细解释这个查询类型。首先,得确定用户对Elasticsearch的基础知识是否了解,但可能他们已经有基本概念,所以直接从Match Query开始。 首先,Match Query属于全文搜索的一种,Term Query的区别可能需要说明。比如,Match会对输入文本进行分析,而Term不会。这里要提到分析器的处理,比如分词、转小写等步骤。 然后,结构部分,用户可能需要知道如何编写一个Match QueryDSL语句。给出一个基本的JSON示例,比如查询"message"字段包含"quick brown fox"的情况。这时候要注意,默认操作符是OR还是AND,用户可能会混淆,需要明确说明,并给出operator参数的用法。 接下来,参数部分很重要。常用的参数包括operator、fuzziness、prefix_length、analyzer等。每个参数的作用适用场景要解释清楚。例如,fuzziness用于模糊匹配,处理拼写错误,而prefix_length控制模糊匹配时起始字符不变的数量。 高级特性方面,比如multi_match,可以扩展到多个字段查询,这里需要简单提及,但可能用户更关注单字段的Match Query。同义词停用词处理也是分析器的一部分,但可能需要提醒用户这些功能依赖于分析器的配置。 性能优化方面,Match Query因为是全文搜索,涉及到分析过程,相比Term Query会更耗资源。使用短语匹配或者结合keyword字段进行精确匹配可能更高效,这些是实际使用中需要注意的地方。 最后,总结Match Query的适用场景,比如需要分词、模糊匹配、处理同义词的情况,以及何时选择其他查询类型。确保用户能根据需求选择合适的查询方式。 可能用户在实际使用中遇到的问题包括为什么某些文档没被检索到,是否因为分词问题或者操作符设置不正确。这时候需要检查分析器的效果operator的参数设置。另外,模糊匹配的参数调整也是常见问题,需要指导如何根据实际情况调整fuzzinessprefix_length。 整体结构需要清晰,分点讲解,让用户能逐步理解Match Query的各个方面,同时提供示例帮助理解。避免使用过于专业的术语,或者至少解释清楚术语的含义,确保不同层次用户都能理解。</think>好的,我来为您详细讲解 Elasticsearch 中的 **Match Query**,这是最常用的全文搜索查询之一。内容会分以下几个部分: --- ### 一、Match Query 的核心特点 1. **全文搜索**:专为处理文本内容设计,会对查询文本进行**分词处理** 2. **分析器生效**:使用字段映射中定义的 analyzer(如 standard、ik 等)进行文本处理 3. **评分机制**:基于 TF/IDF 或 BM25 算法计算相关性得分 4. **与 Term Query 的区别**: - Term Query:精确匹配未经分析的原始词项 - Match Query:先对输入文本进行分析,再搜索分词后的结果 --- ### 二、基础 DSL 结构 ```json GET /_search { "query": { "match": { "field_name": { "query": "search text", "operator": "and" } } } } ``` --- ### 、核心参数详解 #### 1. `operator`(逻辑运算符) - **可选值**:`or`(默认) / `and` - **示例**: ```json "match": { "content": { "query": "elasticsearch tutorial", "operator": "and" // 要求同时包含 "elasticsearch" "tutorial" } } ``` #### 2. `fuzziness`(模糊匹配) - 处理拼写错误,支持 `0`、`1`、`2` 或 `auto` - **示例**: ```json "match": { "title": { "query": "elastiksearch", "fuzziness": "auto" // 可匹配 "elasticsearch" } } ``` #### 3. `prefix_length`(模糊控制) - 指定起始字符不变的数量(减少误匹配) - **典型值**:`3`(前 3 个字符必须精确匹配) #### 4. `analyzer`(自定义分析器) - 覆盖字段默认的分析器设置 - **示例**: ```json "match": { "description": { "query": "数据库优化", "analyzer": "ik_max_word" // 使用 ik 分词器处理查询文本 } } ``` --- ### 四、执行流程解析 1. **查询文本处理**: - 通过指定的分析器进行分词 - 生成 token 列表(如 "quick brown" → ["quick", "brown"]) 2. **生成子查询**: - 根据 `operator` 参数生成 `bool` 查询 - 例如 `operator: "and"` 会生成 `must` 组合查询 3. **相关性评分**: - 计算每个匹配文档的 `_score` - 考虑因素:词项频率、逆文档频率、字段长度等 --- ### 五、典型使用场景 1. **搜索引擎式查询**(用户输入自由文本) 2. **模糊匹配需求**(容忍拼写错误) 3. **多词组合查询**(通过 `operator` 控制逻辑) 4. **多语言支持**(配合对应语言的分词器) --- ### 六、进阶技巧 #### 1. 权重控制 (`boost`) ```json "match": { "tags": { "query": "urgent important", "boost": 2.0 // 提高该条件的权重 } } ``` #### 2. 短语匹配 (`match_phrase`) - 需要保持词序时使用 ```json "match_phrase": { "message": "quick brown fox" } ``` #### 3. 多字段查询 (`multi_match`) ```json { "multi_match": { "query": "elasticsearch", "fields": ["title^3", "content"] // title 字段权重 x3 } } ``` --- ### 七、注意事项 1. **避免用于精确值字段**(如 ID、状态码等) 2. **注意分析器一致性**:索引查询时需使用相同分析器 3. **性能影响**:复杂查询可能影响搜索速度,可结合 `filter` 使用 4. **特殊字符处理**:查询内容中的 `+ - = && || > < !` 等符号需要转义 如果需要更具体的应用场景分析或性能优化建议,可以告诉我您的实际使用需求!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值