Multi Match Query

Multi Match Query

  multi_match查询建议在match query之上,并允许多字段查询:

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

  【1】 查询字符串

  【2】被查询的字段

fields and per-field boosting

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

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

  【1】查询title,first_name和last_name字段。

  个别字段可以通过插入符号(^)来提升:

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

  【1】subject字段是message字段的3倍。

Types of multi_match query:

  内部执行multi_match查询的方式依赖于type参数,它可以被设置成:

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

  most_fields  查找与任何字段匹配的文档,并联合每个字段的_score.

  cross_fields  采用相同分析器处理字段,就好像他们是一个大的字段。在每个字段中查找每个单词。看cross_fields

  phrase    在每个字段上运行match_phrase查询并和每个字段的_score组合。看phrase and phrase_prefix

  phrase_prefix    在每个字段上运行match_phrase_prefix查询并和每个字段的_score组合。看phrase and phrase_prefix

best_fields

  当你在同一个字段中搜索最佳查找的多个单词时,bese_fields类型是最有效的。例如,"brown fox"单独在一个字段中比"brown"在一个字段中和"for"在另外一个字段中更有意义。

  best_fields为每一个字段生成match query并在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类型使用单个最佳匹配字段的score,但是假如tie_breaker被指定,则它通过以下计算score:

  • 来自最佳匹配字段的score
  • 相加所有其他匹配字段的tie_breaker * _score。

  同时也接受analyzerboostoperatorminimum_should_matchfuzzinesslenientprefix_lengthmax_expansionsrewritezero_terms_query和cutoff_frequency作为匹配查询的解释。

  重要:operator 和 minimum_should_match

    best_fields和most_fields类型是field-centric( 他们为每一个字段生成匹配查询)。这意味着为每一个字段单独提供operator和minimum_should_match参数,这可能不是你想要的。

    以此查询为例:

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

    【1】所有的项必须存在

    该查询也可以这样执行:

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

  换句话说,所有项必须在单个字段中存在,以匹配文档。查看cross_fields以寻找更好的解决方案。

most_fields

  当查询使用不同方式包含相同文本分析的多个字段时,most_fields类型是非常有用的。例如,main字段可能包含synonyms,stemming 和没有变音符的项,second字段可能包含original项和third字段包含shingles。通过组合来自三个字段的score,我们能尽可能多的通过main字段匹配文档,但是使用second和third字段将最相似的结果推送到列表的顶部。

  该查询: 

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子句的score将被加在一起,然后通过match子句的数量来分割。

  也接受analyzerboostoperatorminimum_should_matchfuzzinesslenientprefix_lengthmax_expansionsrewritezero_terms_query和cutoff_frequency,作为match query中的解释,但请看operator and minimum_should_match

phrase and phrase_prefix

  phrase和phrase_prefix类型行为就像best_fields,但他们使用match_phrase或者match_phrase_prefix查询代替match查询。

  该查询:

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" }}
      ]
    }
  }
}

  也接受analyzerboostlenientslop 和zero_terms_query作为在match query中的解释。phrase_prefix类型此外接受max_expansions。

  重要:phrase,phrase_prefix和fuzziness:fuzziness参数不能被phrase和phrase_prefix类型使用

cross_fields

  cross_fields类型对于多个字段应该匹配的结构文档特别有用。例如,当为“Will Smith”查询first_name和last_name字段时,最佳匹配应该是"Will"在一个字段中并且"Smith"在另外一个字段中。

   这听起来像most_fields的工作,但这种方法有两个问题。第一个问题是operator和minimum_should_match在每个前缀字段中作用,以代替前缀项(请参考explanation above)。

  第二个问题是与关联性有关:在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_name和last_name索引字段放入单个full_name字段中。当然,这只能在索引时间完成。

  cross_field类型尝试通过采用term-centric方法在查询时解决这些问题。首先把查询字符串分解成当个项,然后在任何字段中查询每个项,就好像它们是一个大的字段。

  查询就像这样:

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)

  换一种说法,所有的项必须至少在匹配文档中一个字段中出现(比较the logic used for best_fields and most_fields)。

  解决了两个问题中的一个。通过混合所有字段项的频率解决不同项匹配的问题,以便平衡差异。

  在实践中,first_name:smith将被视为和last_name:smith具有相同的频率,加1。这将使得在first_name和last_name上的匹配具有可比较的分数,对于last_name具有微小的优势,因为它是最有可能包含simth的字段。

  注意,cross_fields通常仅作用与得到1提升的短字符串字段。 否则增加,项频率和长度正常化有助于得分, 使得项统计的混合不再有任何意义。

  假如你通过Validata API运行上面的查询,将返回这样的解释:

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

  也接受analyzerboostoperatorminimum_should_matchlenientzero_terms_query 和cutoff_frequency,作为match query的解释。

cross_field and analysis

  cross_field类型只能在具有相同分析器的字段上以term-centric模式工作。具有相同分析器的字段如上述实例组合在一起。假如有多个组,则他们使用bool查询相结合。

  例如,假如我们有相同分析器的first和last字段,增加一个同时使用edge_ngram分析器的first.edge和last.edge,该查询:

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])
)

  换句话说,first和last可能被组合在一起并被当做一个字段来对待,同时first.edge和last.edge可能被组合在一起并当做一个字段来对待。

  具有多个组是好的,当使用operator或者minimum_should_match关联的时候,它可能遭受和most_fields和best_fields相同的问题。

  你可以容易的将该查询重写为两个独立的cross_fields查询与bool查询相结合,并将minimum_should_match参数应用于其中一个:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "first", "last" ],
            "minimum_should_match": "50%" 【1】
          }
        },
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "*.edge" ]
          }
        }
      ]
    }
  }
}

  【1】will或smith必须存在于first或last字段。

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

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

  【1】对所有字段使用standard分析器

将执行如下:

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

tie_breaker

  默认情况,每一个per-term混合查询将使用组中任何字段的最佳分数,然后将这些分数相加,以得出最终分数。tie_breaker参数可以改变per-term混合查询的默认行为,它接受:

  0.0       获取最好的分数(举例)first_name:will和last_name:will(default)

  1.0      所有分数相加(举例)first_name:will和last_name:will  

  0.0 < n < 1.0    将单个最佳分数加上tie_breaker乘以其它每个匹配字段的分数。 

  重要:cross_fields and fuzziness

    fuzziness参数不能被cross_fields类型使用。

原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/5.0/query-dsl-multi-match-query.html

时间: 2024-12-11 03:58:10

Multi Match Query的相关文章

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

目录 引言 Match Phase Query slop 参数 analyzer 参数 zero terms query Match Phrase 前缀查询 max_expansions 小结 参考文档 系列文章列表 Query DSL Java Rest Client API 引言 今天再读庄子的<逍遥游>,其中鲲鹏之扶摇直上九万里之气势,蜩(tiao)与学鸠之渺小之对比,令人印象深刻,并对鲲鹏之志心生向往.而郭象在注<庄子>卷中却说,"苟足于其性,则虽大鹏无以自贵于小

MOQL—ElasticSearch转换器(Translator)

MOQL除提供从MOQL语法到Oracle.SQL Server.DB2.MySQL.PostgreSQL等SQL方言的语法转换器外,目前还支持了到ElasticSearch语法的转换.转换器的类名字为org.moql.sql.es.ElasticSearchTranslator.由于MOQL是SQL Like的,所以这个转换器可以完成从SQL语法到ElasticSearch查询语法的转换.由于ElasticSearch查询语法的语义与SQL语法语义各有所长,故MOQL只完成了部分二者语义存在交

elasticsearch技术实战——第一篇(使用篇)

为了提高搜索命中率和准确率,改善现有羸弱的搜索功能,公司决定搭建全文搜索服务.由于之前缺乏全文搜索使用经验,经过一番折腾,终于不负期望按期上线.总结了一些使用心得体会,希望对大家有所帮助.计划分三篇: 第一篇(使用篇),主要讲解基本概念.分词.数据同步.搜索API. 第二篇(配置及参数调优篇),主要围绕JVM参数调优.异常排查.安全性等方面讲解. 第三篇(倒排索引原理篇),知其然知其所以然. 一.技术选型 说到全文搜索大家肯定会想到solr和elasticsearch(以下简称es),两者都是基

Query DSL for elasticsearch Query

Query DSL Query DSL (资料来自: http://www.elasticsearch.cn/guide/reference/query-dsl/) http://elasticsearch.qiniudn.com/ --简介-- elasticsearch 提供基于JSON的完整的Query DSL查询表达式(DSL即领域专用语言). 一般来说, 普通的查询如 term 或者 prefix. 另外还有混合查询如 bool 等. 另外查询表达式(Queries)还能够关联特定的过

50.常用的query查询方式

主要知识点 match all match multi match range query term query terms query exist query 1.match all 查询所有 GET /_search { "query": { "match_all": {} } } 示例: GET /company/employee/_search { "query": { "match_all": {} } } 2.ma

ElasticSearch search api的基础语法+Query DSL搜索+filter与query对比+组合查询+定位不合法的搜索

一. search api的基础语法 1.search语法 GET /search{} GET /index1,index2/type1,type2/search{} GET /_search{ "from": 0, "size": 10} 2.http协议中get是否可以带上request body HTTP协议,一般不允许get请求带上request body,但是因为get更加适合描述查询数据的操作,因此还是这么用了 GET /_search?from=0&a

elasticsearch的javaAPI之query

elasticsearch的javaAPI之query API the Search API允许执行一个搜索查询,返回一个与查询匹配的结果(hits). 它可以在跨一个或多个index上执行, 或者一个或多个types. 查询可以使用提供的 query Java API 或filter Java API . 搜索请求的主体是建立使用 SearchSourceBuilder上. 这里有一个例子: import org.elasticsearch.action.search.SearchRespon

Elasticsearch的javaAPI之query dsl-queries

和rest query dsl一样,elasticsearch提供了一个完整的Java query dsl. 查询建造者(factory)是 QueryBuilders . 一旦准备好您的查询,您可以使用query api. 如何使用QueryBuilders?仅仅就是加入下面的包: import org.elasticsearch.index.query.QueryBuilders.*; 请注意,您可以轻松地打印(又名调试) 查询生成的JSON,用 toString()方法 QueryBuil

Query DSL(2)----Full text queries

Match Query match查询接受文本/数值/日期 { "match" : { "message" : "this is a test" } } match支持三种类型: boolean, phrase,phrase_prefix boolean match查询默认是boolean查询.这意味着现有的文本已通过分析,分析的整个过程就形成了文本的布尔查询(逻辑查询).operator可以是and和or(默认是or)