深度分析 es multi_match 中most_fields、best_fields、cross_fields区别

文章目录

      • [1. `multi_match` 查询的类型](#1. multi_match 查询的类型)
        • [1.1 `best_fields`(默认)](#1.1 best_fields(默认))
        • [1.2 `most_fields`](#1.2 most_fields)
        • [1.3 `cross_fields`](#1.3 cross_fields)
      • [2. 不同类型的示例](#2. 不同类型的示例)
      • [3. 示例 1: 使用 `best_fields`](#3. 示例 1: 使用 best_fields)
      • [4. 示例 2: 使用 `most_fields`](#4. 示例 2: 使用 most_fields)
      • [5. 示例 3: 使用 `cross_fields`](#5. 示例 3: 使用 cross_fields)
      • [6. 返回的结果对比](#6. 返回的结果对比)
      • [7. 总结对比](#7. 总结对比)
      • [8. 总结](#8. 总结)

Elasticsearch 中,multi_match 查询是用来在多个字段中查找匹配的文本。它有不同的 type (类型),例如 most_fieldsbest_fieldscross_fields,这些类型在多字段查询时的匹配策略不同。了解这些类型的区别有助于在不同的场景下做出正确的查询选择。

1. multi_match 查询的类型

1.1 best_fields(默认)

best_fields默认类型。它在多个字段上查找匹配项,并返回与单个字段最匹配的结果。也就是说,ES 会计算每个字段的相关性,然后返回最佳的字段匹配结果。

  • 适用场景 :当你希望查询中的单个字段更重要时,best_fields 适合。
  • 匹配逻辑:多个字段参与查询,但只会选取最好的字段结果。
1.2 most_fields

most_fields 会把多个字段的匹配结果合并到一起,计算最匹配的字段的相关性。每个字段会被视为一个独立的匹配源,并且它们的分数会累加在一起。

  • 适用场景 :当你希望多个字段的匹配对结果有较大影响时,most_fields 适合。
  • 匹配逻辑:多个字段的匹配结果累加,最终的得分是字段得分的总和。
1.3 cross_fields

cross_fields 适用于对多个字段中的数据进行组合查询。它将多个字段合并在一起,类似于一个字段查询。这对于多字段中包含相同概念的情况(例如多个单词分布在不同的字段)尤其有用。

  • 适用场景 :当你希望将多个字段视为同一个字段的组合时,cross_fields 适合。
  • 匹配逻辑:多个字段被视为一个大的字段进行匹配。

2. 不同类型的示例

假设你有一个包含以下字段的 products 索引:

json 复制代码
{
  "product_name": "Wireless Mouse",
  "description": "A wireless mouse with ergonomic design",
  "category": "Electronics"
}

你想要对这几个字段进行查询,可以使用 multi_match 来搜索多个字段。

查询示例数据:
json 复制代码
POST /products/_bulk
{ "index": { "_id": 1 } }
{ "product_name": "Wireless Mouse", "description": "A wireless mouse with ergonomic design", "category": "Electronics" }
{ "index": { "_id": 2 } }
{ "product_name": "Wired Keyboard", "description": "A keyboard with ergonomic design", "category": "Electronics" }
{ "index": { "_id": 3 } }
{ "product_name": "Wireless Keyboard", "description": "Wireless keyboard for gaming", "category": "Electronics" }

3. 示例 1: 使用 best_fields

best_fields 是默认类型,表示从多个字段中选取相关性最强的字段。

查询:
json 复制代码
POST /products/_search
{
  "query": {
    "multi_match": {
      "query": "wireless mouse",
      "fields": ["product_name", "description"],
      "type": "best_fields"
    }
  },
  "explain": true
}
说明:
  • 这个查询会在 product_namedescription 字段上查找匹配,并根据相关性返回最佳的字段匹配结果。
  • 如果 product_name 字段匹配度最高,ES 会选择 product_name 字段作为最终匹配字段。

4. 示例 2: 使用 most_fields

most_fields 会将多个字段的相关性累加。

查询:
json 复制代码
POST /products/_search
{
  "query": {
    "multi_match": {
      "query": "wireless mouse",
      "fields": ["product_name", "description"],
      "type": "most_fields"
    }
  },
  "explain": true
}
说明:
  • 这个查询会把 product_namedescription 两个字段的匹配结果合并,计算它们的总相关性,并返回结果。
  • 比如,product_namedescription 都与查询的 wireless mouse 匹配时,它们的相关性分数会被加在一起。

5. 示例 3: 使用 cross_fields

cross_fields 用于处理多个字段中包含的同一概念时,可以把它们当作一个大的字段进行匹配。

查询:
json 复制代码
POST /products/_search
{
  "query": {
    "multi_match": {
      "query": "wireless mouse",
      "fields": ["product_name", "description"],
      "type": "cross_fields"
    }
  },
  "explain": true
}
说明:
  • 这个查询会把 product_namedescription 视为一个联合字段,来匹配查询词 wireless mouse
  • 即使 wireless mouse 分布在多个字段中(例如,product_name 包含 wirelessdescription 包含 mouse),cross_fields 会将它们合并为一个整体进行匹配。

6. 返回的结果对比

假设你使用了相同的查询词 wireless mouse,结果的排序可能会有所不同,具体取决于查询使用的类型。

  1. best_fields:选择一个字段(最匹配的字段),然后返回与该字段最匹配的文档。
  2. most_fields:计算多个字段的得分,并返回得分最高的文档。
  3. cross_fields:将多个字段视为一个字段进行匹配,从而查找多个字段中的联合匹配。

7. 总结对比

类型 描述 适用场景
best_fields 在多个字段上查找匹配,只选择相关性最强的字段作为最终匹配结果(默认)。 如果只关注单个最相关字段,适用于精确匹配。
most_fields 将多个字段的相关性得分累加,最终返回得分最高的结果。 如果多个字段的匹配结果对最终排序有较大影响。
cross_fields 将多个字段合并为一个整体进行查询,适用于查询词分布在不同字段中的情况。 如果多个字段包含查询的不同部分,且它们属于相同的概念。

8. 总结

  • best_fields 适用于你只关心最相关的字段结果时,通常用于精确匹配查询。
  • most_fields 适用于你希望多个字段的匹配都能影响查询结果时,适合宽松匹配。
  • cross_fields 适用于你希望将多个字段视为一个字段的组合时,尤其是在查询词分布在不同字段中时。
相关推荐
F-2H9 分钟前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
苹果酱056712 分钟前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
_oP_i1 小时前
Pinpoint 是一个开源的分布式追踪系统
java·分布式·开源
mmsx1 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
武子康2 小时前
大数据-258 离线数仓 - Griffin架构 配置安装 Livy 架构设计 解压配置 Hadoop Hive
java·大数据·数据仓库·hive·hadoop·架构
豪宇刘3 小时前
MyBatis的面试题以及详细解答二
java·servlet·tomcat
秋恬意3 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
FF在路上4 小时前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
真的很上进4 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
it噩梦4 小时前
es 中 terms set 使用
大数据·elasticsearch