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
為引數,使用方式和ofollow,noindex" target="_blank">
match
查詢語句
相同
Match Phrase 字首查詢
match_phrase_prefix
和match_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": { "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 敬請期待。