天天看點

[Elasticsearch] 部分比對 (三) - 查詢期間的即時搜尋

本章翻譯自Elasticsearch官方指南的Partial Matching一章。

查詢期間的即時搜尋(Query-time Search-as-you-type)

現在讓我們來看看字首比對能夠如何幫助全文搜尋。使用者已經習慣于在完成輸入之前就看到搜尋結果了 - 這被稱為即時搜尋(Instant Search, 或者Search-as-you-type)。這不僅讓使用者能夠在更短的時間内看到搜尋結果,也能夠引導他們得到真實存在于我們的索引中的結果。

比如,如果使用者輸入了johnnie walker bl,我們會在使用者輸入完成前顯示Johnnie Walker Black Label和Johnnie Walker Blue Label相關的結果。

和往常一樣,有多種方式可以達到我們的目的!首先我們從最簡單的方式開始。你不需要以任何的方式準備你的資料,就能夠在任何全文字段(Full-text Field)上實作即時搜尋。

在短語比對(Phrase Matching)中,我們介紹了match_phrase查詢,它能夠根據單詞順序來比對所有的指定的單詞。對于查詢期間的即時搜尋,我們可以使用該查詢的一個特例,即match_phrase_prefix查詢:

{
    "match_phrase_prefix" : {
        "brand" : "johnnie walker bl"
    }
}      

次查詢和match_phrase查詢的工作方式基本相同,除了它會将查詢字元串中的最後一個單詞當做一個字首。換言之,前面的例子會查找以下内容:

  • johnnie
  • 緊接着的是walker
  • 緊接着的是以bl開頭的單詞

如果我們将該查詢通過validate-query API執行,它會産生如下的解釋:

"johnnie walker bl*"

和match_phrase查詢一樣,它能夠接受一個slop參數(參見這裡)來讓單詞間的順序和相對位置不那麼嚴格:

{
    "match_phrase_prefix" : {
        "brand" : {
            "query": "walker johnnie bl", 
            "slop":  10
        }
    }
}      

但是,查詢字元串中的最後一個單詞總是會被當做一個字首。

在之前介紹prefix查詢的時候,我們談到了prefix查詢的一些需要注意的地方 - prefix查詢時如何消耗資源的。在使用match_phrase_prefix查詢的時候,也面臨着同樣的問題。一個字首a你能夠比對非常非常多的詞條。比對這麼多的詞條不僅會消耗很多資源,同時對于使用者而言也是沒有多少用處的。

我們可以通過将參數max_expansions設定成一個合理的數值來限制字首擴充(Prefix Expansion)的影響,比如50:

{
    "match_phrase_prefix" : {
        "brand" : {
            "query":          "johnnie walker bl",
            "max_expansions": 50
        }
    }
}      

max_expansions參數會控制能夠比對該字首的詞條的數量。它會找到首個以bl開頭的詞條然後開始收集(以字母表順序)直到所有以bl開頭的詞條都被周遊了或者得到了比max_expansions更多的詞條。

不要忘了在使用者每敲入一個字元的時候,該查詢就要被執行一次,是以它的速度需要快。如果第一個結果集不符合使用者的期望,那麼他們就會繼續輸入直到得到他們需要的結果。

繼續閱讀