轉自: 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
過濾器來合併多個過濾器以實現and
,or
和not
邏輯。bool
查詢也做了類似的事,但有一個顯著的不同。
過濾器做出一個二元的決定:這份文檔是否應該被包含在結果列表中?而查詢,則更加微妙。它們不僅要決定是否包含一份文檔,還需要決定這份文檔有多相關。
和過濾器類似,bool
查詢通過must
,must_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
查詢通過將匹配的must
和should
語句的_score
相加,然後除以must
和should
語句的總數來得到相關度分值_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"
如果一份文檔含有所有三個詞條,那麼它會被認爲更相關。