ElasticSearch multi_match多字段匹配

说明

multi_match 与 match 类似,不同的是:能在 多个指定字段 中执行全文检索,无需编写多个 match 查询并通过 bool 组合,大幅简化多字段匹配的语法,且支持灵活的匹配策略和权重调整。

相当于SQL中的 or:

where title like '' or content like ''

字段类型

multi_match 主要用于 text 类型字段(分词),若包含 keyword 类型字段,会按字符串整体匹配;

用法

multi_match 的核心是:将同一个查询字符串,在多个字段上执行匹配,并聚合匹配结果的相关性得分。

最简语法(默认类型)

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "快速的狐狸",  // 要检索的字符串
      "fields": ["title", "content", "description"]  // 要匹配的多个字段
    }
  }
}

上述查询会在 title、content、description 三个字段中,分别执行 match 查询(默认),最终返回任一字段匹配的文档,并按综合得分排序。

字段权重调整

可通过 ^ 为字段设置权重(boost),权重越高,该字段的匹配对最终得分影响越大:

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "快速的狐狸",
      "fields": ["title^3", "content^2", "description"]  // title权重3,content权重2,description默认1
    }
  }
}

示例中,title 字段匹配到关键词时,贡献的得分是普通字段的3倍,适合“标题匹配优先级更高”的场景(如电商商品搜索)。

匹配类型

multi_match 支持多种 type 参数,对应不同的匹配逻辑,是其灵活性的核心。

类型 核心逻辑 适用场景
best_fields(默认) 取多个字段中匹配得分最高的那个字段的得分作为最终得分,其他字段仅辅助 单字段精准匹配(如标题/内容选最优)
most_fields 聚合所有字段的得分(叠加),匹配字段越多得分越高 多字段互补匹配(如标题+摘要+标签)
cross_fields 将多个字段视为一个“大字段”,按词项跨字段匹配(解决“字段拆分导致匹配失效”) 跨字段精准短语匹配(如姓名=姓+名)
phrase 多字段上执行 match_phrase(短语匹配),要求词项顺序+连续 多字段精准短语检索
phrase_prefix 多字段上执行 match_phrase_prefix(短语前缀匹配) 多字段前缀补全(如搜索框联想)
bool_prefix 多字段上执行 bool + 前缀匹配,兼顾分词匹配与前缀容错 高性能前缀检索

best_fields(默认)

应用场景

适合“只要有一个字段精准匹配即可”的场景(如文章搜索,标题匹配优先级远高于正文)。

例子

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "快速的狐狸",
      "fields": ["title^3", "content"],
      "type": "best_fields"  // 可省略,默认值
    }
  }
}

解释:

  • 若 title 匹配到“快速的狐狸”,得分=title得分 * 3;若仅 content 匹配,得分=content得分;

most_fields

应用场景

适合“多维度补充匹配”(如技术文档搜索,标题、摘要、标签都匹配的文档相关性更高)。

例子

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "机器学习",
      "fields": ["title", "abstract", "tags"],
      "type": "most_fields"
    }
  }
}

解释:

  • title+abstract+tags 三个字段中,匹配的字段越多,最终得分越高;

cross_fields

解决“字段拆分导致短语匹配失效”的问题,例如:
文档中 first_name: "张"、last_name: "三",查询“张三”时,普通 best_fields 会因单字段无匹配而失效,cross_fields 可跨字段匹配

例子

GET /user_index/_search
{
  "query": {
    "multi_match": {
      "query": "张三",
      "fields": ["first_name", "last_name"],
      "type": "cross_fields"
    }
  }
}

解释:

  • 核心逻辑:将 张三 分词为[“张”,”三”],然后在 first_name/last_name 中找包含“张”且包含“三”的文档(跨字段匹配词项)。

phrase(多字段短语匹配)

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "快速的狐狸",
      "fields": ["title", "content"],
      "type": "phrase",
      "slop": 1  // 允许词项间隔1个位置
    }
  }
}

解释:

  • 在 title 或 content 字段中,按短语匹配规则(顺序+连续/slop)匹配,仅返回符合短语规则的文档。

关键参数

除 query、fields、type 外,multi_match 还支持以下核心参数:

参数 作用
boost 整体提升查询权重(如 boost: 2,所有字段的匹配得分都×2)
slop 仅对 phrase/phrase_prefix 类型生效,控制短语匹配的词项偏移量
operator 仅对 best_fields/most_fields 生效,可选 OR(默认)/AND,控制是否需匹配所有词项
fuzziness 开启模糊匹配(如 fuzziness: "AUTO"),容错输入错误(如“狐狸”匹配“狐理”)
prefix_length 模糊匹配时,指定词项前缀不参与模糊(如 prefix_length: 2,前2个字符精准匹配)

例子:带模糊匹配的 multi_match

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "快速的狐理",  // 输入错误(理→狸)
      "fields": ["title", "content"],
      "fuzziness": "AUTO",  // 自动适配模糊度
      "prefix_length": 2    // 前2个字符(“快速”)精准匹配,后续允许模糊
    }
  }
}

注意事项

  1. 分析器一致性:多个字段的分析器尽量一致,否则可能因分词结果不同导致匹配异常;
  2. 性能优化:避免在大量字段(如数十个)上使用 multi_match,可通过 fields: ["*_title", "content*"] 通配符简化,但需控制通配符范围;
  3. 得分合理性:best_fields 模式下,若多个字段都匹配,可通过 tie_breaker 参数(0~1)让次要字段的得分参与最终计算(如 tie_breaker: 0.3,最终得分=最优字段得分 + 0.3×其他字段得分)。

例子

在 title、content 2个字段 中查询 带有 java 的记录

GET /toutiao_v1/_search
{
  "query": {
    "multi_match": {
      "query": "java",
      "fields": [
        "title",
        "content"
      ]
    }
  }
}

执行结果:

{
    "took":21,
    "timed_out":false,
    "_shards":{
        "total":1,
        "successful":1,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":{
            "value":3,
            "relation":"eq"
        },
        "max_score":0.4434337,
        "hits":[
            {
                "_index":"toutiao_v2",
                "_type":"_doc",
                "_id":"l91I5nsByvoeiV4PLO3M",
                "_score":0.4434337,
                "_source":{
                    "title":"JAVA技巧",
                    "content":"JAVA高级技巧",
                    "author":"李雷",
                    "like":229,
                    "date":"2021-08-30"
                }
            },
            {
                "_index":"toutiao_v2",
                "_type":"_doc",
                "_id":"md1I5nsByvoeiV4PYe1E",
                "_score":0.4166468,
                "_source":{
                    "title":"JAVA从入门到放弃",
                    "content":"JAVA高手的技巧,java基础、高级",
                    "author":"韩梅梅",
                    "like":983,
                    "date":"2021-08-29"
                }
            },
            {
                "_index":"toutiao_v2",
                "_type":"_doc",
                "_id":"mN1I5nsByvoeiV4PSu3M",
                "_score":0.37365946,
                "_source":{
                    "title":"JAVA mysql技巧大全",
                    "content":"JAVA mysql技巧大全",
                    "author":"李雷",
                    "like":528,
                    "date":"2021-08-29"
                }
            }
        ]
    }
}

五、总结

multi_match 是 Elasticsearch 多字段检索的“一站式解决方案”:

  • 核心优势:简化多字段匹配语法,支持多种匹配策略,可灵活调整字段权重和匹配规则;
  • 核心场景:全文检索(如文章/商品搜索)、跨字段精准匹配(如姓名/地址)、多维度补充匹配(如标题+标签+摘要);
  • 关键选型:根据需求选 type(精准单字段选 best_fields,跨字段短语选 cross_fields,多字段互补选 most_fields)。

原文出处:/show_1IX1rdjRBlrQ.html