Elasticsearch Query DSL 整理總結(三)—— Match Phrase Query 和 Match Phrase Prefix Query

引言

今天再讀莊子的《逍遙遊》,其中鯤鵬之扶搖直上九萬里之氣勢,蜩(tiao)與學鳩之眇小之對比,使人印象深入,並對鯤鵬之志心生嚮往。而郭象在注《莊子》卷中卻說,"苟足於其性,則雖大鵬無以自貴於小鳥,小鳥無羨於天池,而榮願有餘矣。故小大雖殊,逍遙一也。"觀看自身,雖然不是什麼領導,老總,但也徹底沒必要感到爲職業生涯憂慮,只要熱愛程序員這個工做,享受編碼的樂趣,作到 80 歲又有何妨。java

書歸正傳,今天咱們聊聊 Match Phase Query。程序員

Match Phase Query

match_phrase 查詢針對的是一個語句,好比 "like football", 分析時也會將整個語句做爲總體,而不會像上篇的 match 查詢 會將整個語句拆分爲單個詞條。json

舉個例子,建立一個 match_phase type 並塞進去一個文檔, message 是 I like swimming and riding!api

PUT matchphasetest
{}

PUT matchphasetest/_mapping/match_phase
{
  "properties": {
    "message": {
      "type": "text"
    }
  }
}

PUT matchphasetest/match_phase/1
{
  "message": "I like swimming and riding!"
}

GET matchphasetest/_search
{
  "query": {
    "match_phrase": {
      "message": "I like swimming"
    }
  }
}

默認使用 match_phrase 時會精確匹配查詢的短語,須要所有單詞和順序要徹底同樣,標點符號除外。app

slop 參數

這種精確匹配在大部分狀況下顯得太嚴苛了,有時咱們想要包含 ""I like swimming and riding!"" 的文檔也可以匹配 "I like riding"。這時就要以用到 "slop" 參數來控制查詢語句的靈活度。elasticsearch

slop 參數告訴 match_phrase 查詢詞條相隔多遠時仍然能將文檔視爲匹配 什麼是相隔多遠? 意思是說爲了讓查詢和文檔匹配你須要移動詞條多少次?ide

以 "I like swimming and riding!" 的文檔爲例,想匹配 "I like riding",只須要將 "riding" 詞條向前移動兩次,所以設置 slop 參數值爲 2, 就能夠匹配到。ui

GET matchphasetest/_search
{
  "query": {
    "match_phrase": {
      "message": {
        "query": "I like riding",
        "slop": 2
      }
    }
  }
}

analyzer 參數

match_phrase 語句也能夠設置 analyzer 參數來定義查詢語句時對其中詞條執行的分析過程。this

默認狀況下,使用的是建立 mapping 時的分析器,若是沒有指定就會使用默認的查詢分析器。這裏舉個例子(只是如何使用)

GET /_search
{
    "query": {
        "match_phrase" : {
            "message" : {
                "query" : "this is a test",
                "analyzer" : "my_analyzer"
            }
        }
    }
}

zero terms query

match_phrase 也接受 zero_terms_query 爲參數,使用方式和 match查詢語句相同

Match Phrase 前綴查詢

match_phrase_prefixmatch_phrase 用法是同樣的,區別就在於它容許對最後一個詞條前綴匹配。以上節的數據爲例,查詢 I like sw 就能匹配到

I like swimming and riding

GET matchphasetest/_search
{
  "query": {
    "match_phrase_prefix": {
      "message": "I like swi"
    }
  }
}

max_expansions

官方文檔中說 match_phrase_prefix 查詢中有個參數 max_expansions 說的是參數 max_expansions 控制着能夠與前綴匹配的詞的數量,默認值是 50。

I like swi 查詢爲例,它會先查找第一個與前綴 swi 匹配的詞,而後依次查找蒐集與之匹配的詞(按字母順序),直到沒有更多可匹配的詞或當數量超過 max_expansions 時結束。

可是我在使用時,故意造出了數十個以 swi 開頭的詞,而將 max_expansions 的值設爲 10。可是卻返回了全部的結果。在 elasitc 官網也有對該問題的討論, 也是沒有找到答案。這個問題做爲一個公案權且記下,若是您知道緣由,麻煩告訴我,很是感謝。

這裏也貼出個例子,以備後面排查

GET matchphaseprefixtest/_search
{
  "query": {
    "match_phrase_prefix": {
      "message": {
        "query": "I like sw",
        "max_expansions": 10
       }
    }
  }
}

match_phrase_prefix 用起來很是方便,可以實現輸入即搜索的效果,可是也會出現問題。 假如說查詢 I like s 而且想要匹配 I like swimming ,結果是默認狀況下它會搜索出前 50 個組合,若是前 50 個沒有 swimming ,那就不會顯示出結果。只能是用戶繼續輸入後面的字母纔可能匹配出結果。

要實現更好的即便搜索的特性,能夠看看 completion suggester
Index-Time Search-as-You-Type 能不能實現。

小結

本文論述了 Match Phase Query 和 Match Phrase 前綴查詢 的使用,下文會講解 Multi Match Query 敬請期待。

參考文檔

1.Match Phrase Query

系列文章列表

Query DSL

  1. Query DSL 概要,MatchAllQuery,全文查詢簡述
  2. Match Query

Java Rest Client API

  1. Elasticsearch Java Rest Client API 整理總結 (一)——Document API
  2. Elasticsearch Java Rest Client API 整理總結 (二) —— SearchAPI
  3. Elasticsearch Java Rest Client API 整理總結 (三)——Building Queries
相關文章
相關標籤/搜索