全文搜索 (二) - 多詞查詢及查詢的合併

轉自: http://blog.csdn.net/dm_vincent/article/details/41720193

多詞查詢(Multi-word Queries)

如果我們一次只能搜索一個詞,那麼全文搜索就會顯得相當不靈活。幸運的是,通過match查詢來實現多詞查詢也同樣簡單:

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "BROWN DOG!"
        }
    }
}

以上的查詢會返回所有的四份文檔:

{
  "hits": [
     {
        "_id":      "4",
        "_score":   0.73185337, 
        "_source": {
           "title": "Brown fox brown dog"
        }
     },
     {
        "_id":      "2",
        "_score":   0.47486103, 
        "_source": {
           "title": "The quick brown fox jumps over the lazy dog"
        }
     },
     {
        "_id":      "3",
        "_score":   0.47486103, 
        "_source": {
           "title": "The quick brown fox jumps over the quick dog"
        }
     },
     {
        "_id":      "1",
        "_score":   0.11914785, 
        "_source": {
           "title": "The quick brown fox"
        }
     }
  ]
}

文檔4的相關度最高因爲它包含了"brown"兩次和"dog"一次。 文檔2和文檔3都包含了"brown""dog"一次,同時它們的title字段擁有相同的長度,因此它們的分值相同。 文檔1只包含了"brown"

因爲match查詢需要查詢兩個詞條 - ["brown","dog"] - 在內部它需要執行兩個term查詢,然後將它們的結果合併來得到整體的結果。因此,它會將兩個term查詢通過一個bool查詢組織在一起,我們會在合併查詢一節中詳細介紹。

從上面的例子中需要吸取的經驗是,文檔的title字段中只需要包含至少一個指定的詞條,就能夠匹配該查詢。如果匹配的詞條越多,也就意味着該文檔的相關度就越高。

提高精度(Improving Precision)

匹配任何查詢詞條就算作匹配的話,會導致最終結果中有很多看似無關的匹配。它是一個霰彈槍式的策略(Shotgun Approach)。我們大概只想要顯示包含了所有查詢詞條的文檔。換言之,相比brown OR dog,我們更想要的結果是brown AND dog

match查詢接受一個operator參數,該參數的默認值是"or"。你可以將它改變爲"and"來要求所有的詞條都需要被匹配:

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": {      
                "query":    "BROWN DOG!",
                "operator": "and"
            }
        }
    }
}

match查詢的結構需要被稍稍改變來容納operator參數。

這個查詢的結果會將文檔1排除在外,因爲它只包含了一個查詢詞條。

控制精度(Controlling Precision)

在all和any中選擇有種非黑即白的感覺。如果用戶指定了5個查詢詞條,而一份文檔只包含了其中的4個呢?將"operator"設置成"and"會將它排除在外。

有時候這正是你想要的,但是對於大多數全文搜索的使用場景,你會希望將相關度高的文檔包含在結果中,將相關度低的排除在外。換言之,我們需要一種介於兩者中間的方案。

match查詢支持minimum_should_match參數,它能夠讓你指定有多少詞條必須被匹配纔會讓該文檔被當做一個相關的文檔。儘管你能夠指定一個詞條的絕對數量,但是通常指定一個百分比會更有意義,因爲你無法控制用戶會輸入多少個詞條:

GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": {
        "query":                "quick brown dog",
        "minimum_should_match": "75%"
      }
    }
  }
}

當以百分比的形式指定時,minimum_should_match會完成剩下的工作:在上面擁有3個詞條的例子中,75%會被向下舍入到66.6%,即3個詞條中的2個。無論你輸入的是什麼,至少有2個詞條被匹配時,該文檔纔會被算作最終結果中的一員。

minimum_should_match參數非常靈活,根據用戶輸入的詞條的數量,可以適用不同的規則。具體可以參考minimum_should_match參數的相關文檔

爲了更好地瞭解match查詢是如何處理多詞查詢的,我們需要看看bool查詢是如何合併多個查詢的。


合併查詢(Combining Queries)

合併過濾器中我們討論了使用bool過濾器來合併多個過濾器以實現andornot邏輯。bool查詢也做了類似的事,但有一個顯著的不同。

過濾器做出一個二元的決定:這份文檔是否應該被包含在結果列表中?而查詢,則更加微妙。它們不僅要決定是否包含一份文檔,還需要決定這份文檔有多相關。

和過濾器類似,bool查詢通過mustmust_not以及should參數來接受多個查詢。比如:

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must":     { "match": { "title": "quick" }},
      "must_not": { "match": { "title": "lazy"  }},
      "should": [
                  { "match": { "title": "brown" }},
                  { "match": { "title": "dog"   }}
      ]
    }
  }
}

title字段中含有詞條quick,且不含有詞條lazy的任何文檔都會被作爲結果返回。目前爲止,它的工作方式和bool過濾器十分相似。

差別來自於兩個should語句,它表達了這種意思:一份文檔不被要求需要含有詞條brown或者dog,但是如果它含有了,那麼它的相關度應該更高。

{
  "hits": [
     {
        "_id":      "3",
        "_score":   0.70134366, 
        "_source": {
           "title": "The quick brown fox jumps over the quick dog"
        }
     },
     {
        "_id":      "1",
        "_score":   0.3312608,
        "_source": {
           "title": "The quick brown fox"
        }
     }
  ]
}

文檔3的分值更高因爲它包含了brown以及dog

分值計算(Score Calculation)

bool查詢通過將匹配的mustshould語句的_score相加,然後除以mustshould語句的總數來得到相關度分值_score

must_not語句不會影響分值;它們唯一的目的是將不需要的文檔排除在外。

控制精度(Controlling Precision)

所有的must語句都需要匹配,而所有的must_not語句都不能匹配,但是should語句需要匹配多少個呢?默認情況下,should語句一個都不要求匹配,只有一個特例:如果查詢中沒有must語句,那麼至少要匹配一個should語句。

正如我們可以控制match查詢的精度,我們也能夠通過minimum_should_match參數來控制should語句需要匹配的數量,該參數可以是一個絕對數值或者一個百分比:

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "brown" }},
        { "match": { "title": "fox"   }},
        { "match": { "title": "dog"   }}
      ],
      "minimum_should_match": 2 
    }
  }
}

以上查詢的而結果僅包含以下文檔:

title字段包含: "brown" AND "fox" 或者 "brown" AND "dog" 或者 "fox" AND "dog"

如果一份文檔含有所有三個詞條,那麼它會被認爲更相關。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章