当前位置: 首页 > 工具软件 > quick-query > 使用案例 >

multi_match query

田镜
2023-12-01

multi_match查询建立在match query的基础上,允许多字段查询:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

fields和字段增强

可以使用通配符指定字段,例如:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "Will Smith",
      "fields": [ "title", "*_name" ] 
    }
  }
}

单个字段可以通过插入符号(^)来增强:

GET /_search
{
  "query": {
    "multi_match" : {
      "query" : "this is a test",
      "fields" : [ "subject^3", "message" ] 
    }
  }
}

该查询将subject字段的分数乘以3,但保持message字段的分数不变。

如果没有提供字段,multi_match查询默认为index.query.default_field索引设置,而后者默认为*。*提取映射中符合术语查询条件的所有字段,并过滤元数据字段。然后将所有提取的字段组合起来构建一个查询。

mutil_match的type类型:

multi_match查询在内部执行的方式取决于type参数,可以将其设置为:

best_fields

(默认) 查找与任何字段匹配的文档,但使用_score来自最佳字段的文档 。见best_fields

most_fields

查找与任何字段匹配的文档并组合来自每个字段的_score 。见most_fields

cross_fields

像对待analyzer一个大字段一样对待字段。在任何 字段中查找每个单词。见cross_fields

phrase

对每个字段运行match_phrase查询并使用_score 来自最佳字段的查询。见phrase和phrase_prefix

phrase_prefix

对每个字段运行match_phrase_prefix查询并使用_score来自最佳字段的查询。见phrase和phrase_prefix

bool_prefix

在每个字段上创建一个match_bool_prefix查询并组合_score来自每个字段的 。见 bool_prefix

best_fields

best_fields类型在搜索多个在同一字段中最容易找到的单词时最有用。例如,单个字段中的“brown fox”要比一个字段中的“brown”和另一个字段中的“fox”更有意义。

best_fields类型为每个字段生成一个匹配查询,并将它们包装在dis_max查询中,以找到唯一的最佳匹配字段。例如,下面的查询:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "brown fox",
      "type":       "best_fields",
      "fields":     [ "subject", "message" ],
      "tie_breaker": 0.3
    }
  }
}

 将以下列方式执行:

GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        { "match": { "subject": "brown fox" }},
        { "match": { "message": "brown fox" }}
      ],
      "tie_breaker": 0.3
    }
  }
}

通常情况下,best_fields类型使用单个最佳匹配字段的得分,但如果指定了tie_breaker,则它计算得分如下:

  • 来自最佳匹配字段的分数
  • 加上tie_breaker * _score所有其他匹配字段

此外,接受analyzer、boost、operator、minimum_should_match、fuzziness、lenient、prefix_length、max_expansions、fuzzy_rewrite、zero_terms_query、cutoff_frequency、auto_generate_synonyms_phrase_query和fuzzy_transposition,如匹配查询中解释的。

most_fields

most_fields当查询包含以不同方式分析的相同文本的多个字段时,该类型最有用。例如,主字段可能包含同义词、词干和没有变音符号的术语。第二个字段可能包含原始术语,第三个字段可能包含带状疱疹。通过结合所有三个字段的分数,我们可以将尽可能多的文档与主字段匹配,但使用第二个和第三个字段将最相似的结果推送到列表顶部。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown fox",
      "type":       "most_fields",
      "fields":     [ "title", "title.original", "title.shingles" ]
    }
  }
}

将以下列方式执行:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":          "quick brown fox" }},
        { "match": { "title.original": "quick brown fox" }},
        { "match": { "title.shingles": "quick brown fox" }}
      ]
    }
  }
}

每个match子句的得分加在一起,然后除以match子句的数量。

此外,接受analyzer、boost、operator、minimum_should_match、fuzziness、lenient、prefix_length、max_expansions、fuzzy_rewrite、zero_terms_query和cutoff_frequency,如匹配查询中解释的,但请参见operator和minimum_should_match。

phrase和phrase_prefix

phrase和phrase_prefix类型的行为类似于best_fields,但它们使用match_phrase或match_phrase_prefix查询而不是匹配查询。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown f",
      "type":       "phrase_prefix",
      "fields":     [ "subject", "message" ]
    }
  }
}

将以以下方式执行:

GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        { "match_phrase_prefix": { "subject": "quick brown f" }},
        { "match_phrase_prefix": { "message": "quick brown f" }}
      ]
    }
  }
}

此外,接受analyzer、boost、lenient和zero_terms_query,如Match中解释的,以及slop,在Match短语中解释。类型phrase_prefix另外接受max_expansions。

cross_fields

cross_fields类型与结构化文档在多个领域特别有用应该相匹配。例如,当查询first_name 和last_name字段中的“Will Smith”时,最佳匹配很可能在一个字段中包含“Will”而在另一个字段中包含“Smith”。

这听起来像是most_fields的工作,但这种方法有两个问题。第一个问题是,operater和minimum_should_match是针对每个字段应用的,而不是针对每个term(参见上面的解释)。
第二个问题与相关性有关:first_name和last_name字段中的不同术语频率可能会产生意想不到的结果。
例如,假设我们有两个人:“Will Smith” 和 “Smith Jones”。“Smith”作为姓很常见(所以不太重要),但“Smith”作为名很不常见(所以很重要)。
如果我们搜索“Will Smith”,“Smith Jones”文档可能会出现在更匹配的“Will Smith”上面,因为first_name: Smith的得分超过了first_name: Will加last_name: Smith的得分之和。

 处理这些类型的查询的一种方法是简单地将first_namelast_name字段索引 到单个full_name字段中。当然,这只能在索引时完成。

cross_field类型试图通过采用以术语为中心的方法在查询时解决这些问题 。它首先将查询字符串分析为单独的术语,然后在任何字段中查找每个术语,就好像它们是一个大字段一样。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and"
    }
  }
}

执行:

+(first_name:will last_name:will)
+(first_name:smith last_name:smith)

换句话说,所有术语必须至少出现在一个字段中才能匹配文档。(将此与用于best_fields和的逻辑most_fields进行比较 。)

这解决了两个问题之一。不同词频的问题是通过混合所有领域的词频来解决的,以消除差异。

在实践中,first_name:smith将被视为与 last_name:smith具有相同的频率,加一。这将使匹配 first_namelast_name具有可比的分数,last_name因为它是最有可能包含smith.

注意,cross_fields通常只对boost为1的短字符串字段有用。除此之外,术语频率和长度标准化也会对分数产生影响,从而导致术语统计数据的混合不再有意义。

如果你通过Validate运行上面的查询,它会返回如下解释:

+blended("will",  fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])

此外,接受analyzer、boost、operator、minimum_should_match、lenient、zero_terms_query和cutoff_frequency,如匹配查询中解释的那样。

cross_field和analysis

cross_field类型只能在具有相同分析器的字段上以术语为中心模式工作。与上面的示例一样,使用同一个分析器的字段被分组在一起。如果有多个组,查询将使用任何组中的最佳分数。

例如,如果我们有一个firstlast字段,它们具有相同的分析器,加上 first.edge并且last.edge都使用edge_ngram 分析器,则此查询:

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Jon",
      "type":       "cross_fields",
      "fields":     [
        "first", "first.edge",
        "last",  "last.edge"
      ]
    }
  }
}

将以下列方式执行:

  blended("jon", fields: [first, last])
| (
    blended("j",   fields: [first.edge, last.edge])
    blended("jo",  fields: [first.edge, last.edge])
    blended("jon", fields: [first.edge, last.edge])
)

换句话说,firstandlast将被组合在一起并被视为单个字段,并且first.edgelast.edge将被组合在一起并被视为单个字段。

拥有多个组很好,但是当与operator或minimum_should_match组合时,它可能会遇到与most_fields或best_fields相同的问题。

您可以很容易地自己将这个查询重写为两个独立的cross_fields查询结合dis_max查询,并仅对其中一个应用minimum_should_match参数:

GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "first", "last" ],
            "minimum_should_match": "50%" 
          }
        },
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "*.edge" ]
          }
        }
      ]
    }
  }
}

通过在查询中指定analyzer参数,可以将所有字段强制放入同一组。

GET /_search
{
  "query": {
   "multi_match" : {
      "query":      "Jon",
      "type":       "cross_fields",
      "analyzer":   "standard", 
      "fields":     [ "first", "last", "*.edge" ]
    }
  }
}

执行方式如下:

blended("will",  fields: [first, first.edge, last.edge, last])
blended("smith", fields: [first, first.edge, last.edge, last])

tie_breaker

默认情况下,每个词混合查询将使用组中任何字段返回的最佳分数。然后,在组合不同组的分数时,查询使用任何组的最佳分数。tie_breaker参数可以改变这两个步骤的行为:

0.0

从(例如)first_name:will 和last_name:will(默认)中 取出单个最佳分数

1.0

将 (eg)first_name:will和 last_name:will

0.0 < n < 1.0

取单个最佳分数加上tie_breaker乘以其他匹配字段/组的每个分数

bool_prefix 

bool_prefix类型的评分行为类似于most_fields,但使用 match_bool_prefix查询而不是 match查询。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown f",
      "type":       "bool_prefix",
      "fields":     [ "subject", "message" ]
    }
  }
}

支持匹配查询中解释的analyzer、boost、operator、minimum_should_match、lenient、zero_terms_query和auto_generate_synonyms_phrase_query参数。用于构造词汇查询的词汇支持fuzzy、prefix_length、max_expansions、fuzzy_rewrite和fuzzy_transpositions参数,但对从最后一个词汇构造的前缀查询没有影响。

这种查询类型不支持slop和cutoff_frequency参数。

 类似资料:

相关阅读

相关文章

相关问答