如果一次只能查詢一個關鍵詞,全文檢索將會很不方便。幸運的是,用match查詢進行多詞查詢也很簡單:
GET /my_index/my_type/_search
{
"query": {
"match": {
"title": "BROWN DOG!"
}
}
}
上面這個查詢返回以下結果集:
{
"hits": [
{
"_id": "4",
"_score": 0.73185337, <1>
"_source": {
"title": "Brown fox brown dog"
}
},
{
"_id": "2",
"_score": 0.47486103, <2>
"_source": {
"title": "The quick brown fox jumps over the lazy dog"
}
},
{
"_id": "3",
"_score": 0.47486103, <2>
"_source": {
"title": "The quick brown fox jumps over the quick dog"
}
},
{
"_id": "1",
"_score": 0.11914785, <3>
"_source": {
"title": "The quick brown fox"
}
}
]
}
<1> 文檔4的相關度最高,因為包含兩個"brown"和一個"dog"。
<2> 文檔2和3都包含一個"brown"和一個"dog",且'title'字段長度相同,所以相關度相等。
<3> 文檔1只包含一個"brown",不包含"dog",所以相關度最低。
因為match查詢需要查詢兩個關鍵詞:"brown"和"dog",在內部會執行兩個term查詢並綜合二者的結果得到最終的結果。match的實現方式是將兩個term查詢放入一個bool查詢,bool查詢在之前的章節已經介紹過。
重要的一點是,'title'字段包含至少一個查詢關鍵字的文檔都被認為是符合查詢條件的。匹配的單詞數越多,文檔的相關度越高。
提高精度
匹配包含任意個數查詢關鍵字的文檔可能會得到一些看似不相關的結果,這是一種霰彈策略(shotgun approach)。然而我們可能想得到包含所有查詢關鍵字的文檔。換句話說,我們想得到的是匹配'brown AND dog'的文檔,而非'brown OR dog'。
match查詢接受一個'operator'參數,默認值為or。如果要求所有查詢關鍵字都匹配,可以更改參數值為and:
GET /my_index/my_type/_search
{
"query": {
"match": {
"title": { <1>
"query": "BROWN DOG!",
"operator": "and"
}
}
}
}
<1> 為了加入``'operator'``參數,``match``查詢的結構有一些不同。
這個查詢會排除文檔1,因為文檔1只包含了一個查詢關鍵詞。
控制精度
在 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'被設置為百分數時,查詢進行如下:在上面的例子里,'75%'會被下舍為'66.6%',也就是2個關鍵詞。不論參數值為多少,進入結果集的文檔至少應匹配一個關鍵詞。
[提示]
'minimum_should_match'參數很靈活,根據用戶輸入的關鍵詞個數,可以采用不同的匹配規則。更詳細的內容可以查看文檔。
要全面理解match查詢是怎樣處理多詞查詢,我們需要了解怎樣用bool查詢合並多個查詢
