1. 程式人生 > >Multi Match Query

Multi Match Query

www 第一個 其他 origin 應該 exp 我們 types second

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。

  同時也接受analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_terms_query和cutoff_frequency作為匹配查詢的解釋。

  重要:operatorminimum_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子句的數量來分割。

  也接受analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_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" }}
      ]
    }
  }
}

  也接受analyzer, boost, lenient, slopzero_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])

  也接受analyzer, boost, operator, minimum_should_match, lenient, zero_terms_querycutoff_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

Multi Match Query