目錄html
今天再讀莊子的《逍遙遊》,其中鯤鵬之扶搖直上九萬里之氣勢,蜩(tiao)與學鳩之眇小之對比,使人印象深入,並對鯤鵬之志心生嚮往。而郭象在注《莊子》卷中卻說,"苟足於其性,則雖大鵬無以自貴於小鳥,小鳥無羨於天池,而榮願有餘矣。故小大雖殊,逍遙一也。"觀看自身,雖然不是什麼領導,老總,但也徹底沒必要感到爲職業生涯憂慮,只要熱愛程序員這個工做,享受編碼的樂趣,作到 80 歲又有何妨。java
書歸正傳,今天咱們聊聊 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
這種精確匹配在大部分狀況下顯得太嚴苛了,有時咱們想要包含 ""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 } } } }
match_phrase
語句也能夠設置 analyzer
參數來定義查詢語句時對其中詞條執行的分析過程。this
默認狀況下,使用的是建立 mapping 時的分析器,若是沒有指定就會使用默認的查詢分析器。這裏舉個例子(只是如何使用)
GET /_search { "query": { "match_phrase" : { "message" : { "query" : "this is a test", "analyzer" : "my_analyzer" } } } }
match_phrase
也接受 zero_terms_query
爲參數,使用方式和 match
查詢語句相同
match_phrase_prefix
和 match_phrase
用法是同樣的,區別就在於它容許對最後一個詞條前綴匹配。以上節的數據爲例,查詢 I like sw
就能匹配到
I like swimming and riding
。
GET matchphasetest/_search { "query": { "match_phrase_prefix": { "message": "I like swi" } } }
官方文檔中說 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 敬請期待。