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


引言

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

書歸正傳,今天我們聊聊 Match Phase Query。

Match Phase Query

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

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

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 時會精確匹配查詢的短語,需要全部單詞和順序要完全一樣,標點符號除外。

slop 參數

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

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

以 "I like swimming and riding!" 的文檔為例,想匹配 "I like riding",只需要將 "riding" 詞條向前移動兩次,因此設置 slop 參數值為 2, 就可以匹配到。

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

analyzer 參數

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

默認情況下,使用的是創建 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM