[Elasticsearch] 鄰近匹配 (一) - 短語匹配以及slop參數

鄰近匹配(Proximity Matching)

 

使用了TF/IDF的標準全文搜索將文檔,或者至少文檔中的每一個字段,視做"一大袋的單詞"(Big bag of Words)。match查詢可以告訴咱們這個袋子中是否包含了咱們的搜索詞條,可是這只是一個方面。它不能告訴咱們關於單詞間關係的任何信息。html

考慮如下這些句子的區別:elasticsearch

  • Sue ate the alligator.
  • The alligator ate Sue.
  • Sue never goes anywhere without her alligator-skin purse.

一個使用了sue alligator的match查詢會匹配以上全部文檔,可是它沒法告訴咱們這兩個詞是否表達了部分原文的部分意義,或者是表達了完整的意義。ide

理解單詞間的聯繫是一個複雜的問題,咱們也沒法僅僅依靠另外一類查詢就解決這個問題,可是咱們至少能夠經過單詞間的距離來判斷單詞間可能的關係。ui

真實的文檔也許比上面幾個例子要長的多:Sue和alligator也許相隔了幾個段落。也許咱們仍然但願包含這樣的文檔,可是咱們會給那些Sue和alligator出現的較近的文檔更高的相關度分值。spa

這就是短語匹配(Phrase Matching),或者鄰近度匹配(Proximity Matching)。code

TIPhtm

本章中,咱們仍然會使用match查詢中使用的示例文檔。索引

 

 

 

短語匹配(Phrase Matching)

 

就像一提到全文搜索會首先想到match查詢同樣,當你須要尋找鄰近的幾個單詞時,你會使用match_phrase查詢:token

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": "quick brown fox"
        }
    }
}

和match查詢相似,match_phrase查詢首先解析查詢字符串來產生一個詞條列表。而後會搜索全部的詞條,但只保留含有了全部搜索詞條的文檔,而且詞條的位置要鄰接。一個針對短語quick fox的查詢不會匹配咱們的任何文檔,由於沒有文檔含有鄰接在一塊兒的quick和box詞條。文檔

TIP

match_phrase查詢也能夠寫成類型爲phrase的match查詢:

"match": {
    "title": {
        "query": "quick brown fox",
        "type":  "phrase"
    }
}

詞條位置

當一個字符串被解析時,解析器不只只返回一個詞條列表,它同時也返回每一個詞條的位置,或者順序信息:

GET /_analyze?analyzer=standard
Quick brown fox

會返回如下的結果:

{
   "tokens": [
      {
         "token": "quick",
         "start_offset": 0,
         "end_offset": 5,
         "type": "<ALPHANUM>",
         "position": 1 
      },
      {
         "token": "brown",
         "start_offset": 6,
         "end_offset": 11,
         "type": "<ALPHANUM>",
         "position": 2 
      },
      {
         "token": "fox",
         "start_offset": 12,
         "end_offset": 15,
         "type": "<ALPHANUM>",
         "position": 3 
      }
   ]
}

位置信息能夠被保存在倒排索引(Inverted Index)中,像match_phrase這樣位置感知(Position-aware)的查詢可以使用位置信息來匹配那些含有正確單詞出現順序的文檔,在這些單詞間沒有插入別的單詞。

短語是什麼

對於匹配了短語"quick brown fox"的文檔,下面的條件必須爲true:

  • quick,brown和fox必須所有出如今某個字段中。
  • brown的位置必須比quick的位置大1。
  • fox的位置必須比quick的位置大2。

若是以上的任何條件沒有被知足,那麼文檔就不能被匹配。

TIP

在內部,match_phrase查詢使用了低級的span查詢族(Query Family)來執行位置感知的查詢。span查詢是詞條級別的查詢,所以它們沒有解析階段(Analysis Phase);它們直接搜索精確的詞條。

幸運的是,大多數用戶幾乎不須要直接使用span查詢,由於match_phrase查詢一般已經夠好了。可是,對於某些特別的字段,好比專利搜索(Patent Search),會使用這些低級查詢來執行擁有很是特別構造的位置搜索。

 

 

 

混合起來(Mixing it up)

 

精確短語(Exact-phrase)匹配也許太過於嚴格了。也許咱們但願含有"quick brown fox"的文檔也可以匹配"quick fox"查詢,即便位置並非徹底相等的。

咱們能夠在短語匹配使用slop參數來引入一些靈活性:

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": {
                "query": "quick fox",
                "slop":  1
            }
        }
    }
}

slop參數告訴match_phrase查詢詞條可以相隔多遠時仍然將文檔視爲匹配。相隔多遠的意思是,你須要移動一個詞條多少次來讓查詢和文檔匹配?

咱們以一個簡單的例子來闡述這個概念。爲了讓查詢quick fox可以匹配含有quick brown fox的文檔,咱們須要slop的值爲1:

 
  1. Pos 1 Pos 2 Pos 3

  2. -----------------------------------------------

  3. Doc: quick brown fox

  4. -----------------------------------------------

  5. Query: quick fox

  6. Slop 1: quick ↳ fox

儘管在使用了slop的短語匹配中,全部的單詞都須要出現,可是單詞的出現順序能夠不一樣。若是slop的值足夠大,那麼單詞的順序能夠是任意的。

爲了讓fox quick查詢可以匹配咱們的文檔,須要slop的值爲3:

 
  1. Pos 1 Pos 2 Pos 3

  2. -----------------------------------------------

  3. Doc: quick brown fox

  4. -----------------------------------------------

  5. Query: fox quick

  6. Slop 1: fox|quick ↵

  7. Slop 2: quick ↳ fox

  8. Slop 3: quick ↳ fox

相關文章
相關標籤/搜索