[Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 译
multi_match查詢
multi_match查詢提供了一個(gè)簡便的方法用來對多個(gè)字段執(zhí)行相同的查詢。
NOTE
存在幾種類型的multi_match查詢,其中的3種正好和在“了解你的數(shù)據(jù)”一節(jié)中提到的幾種類型相同:best_fields,most_fields以及cross_fields。
默認(rèn)情況下,該查詢以best_fields類型執(zhí)行,它會(huì)為每個(gè)字段生成一個(gè)match查詢,然后將這些查詢包含在一個(gè)dis_max查詢中。下面的dis_max查詢:
1 { 2 "dis_max": { 3 "queries": [ 4 { 5 "match": { 6 "title": { 7 "query": "Quick brown fox", 8 "minimum_should_match": "30%" 9 } 10 } 11 }, 12 { 13 "match": { 14 "body": { 15 "query": "Quick brown fox", 16 "minimum_should_match": "30%" 17 } 18 } 19 }, 20 ], 21 "tie_breaker": 0.3 22 } 23 }可以通過multi_match簡單地重寫如下:
1 { 2 "multi_match": { 3 "query": "Quick brown fox", 4 "type": "best_fields", 5 "fields": [ "title", "body" ], 6 "tie_breaker": 0.3, 7 "minimum_should_match": "30%" 8 } 9 }注意到以上的type屬性為best_fields。?minimum_should_match和operator參數(shù)會(huì)被傳入到生成的match查詢中。
在字段名中使用通配符
字段名可以通過通配符指定:任何匹配了通配符的字段都會(huì)被包含在搜索中。你可以通過下面的查詢來匹配book_title,chapter_title以及section_title字段:
1 { 2 "multi_match": { 3 "query": "Quick brown fox", 4 "fields": "*_title" 5 } 6 }提升個(gè)別字段
個(gè)別字段可以通過caret語法(^)進(jìn)行提升:僅需要在字段名后添加^boost,其中的boost是一個(gè)浮點(diǎn)數(shù):
1 { 2 "multi_match": { 3 "query": "Quick brown fox", 4 "fields": [ "*_title", "chapter_title^2" ] 5 } 6 }chapter_title字段的boost值為2,而book_title和section_title字段的boost值為默認(rèn)的1。
?
多數(shù)字段(Most Fields)
全文搜索是一場召回率(Recall) - 返回所有相關(guān)的文檔,以及準(zhǔn)確率(Precision) - 不返回?zé)o關(guān)文檔,之間的戰(zhàn)斗。目標(biāo)是在結(jié)果的第一頁給用戶呈現(xiàn)最相關(guān)的文檔。
為了提高召回率,我們會(huì)廣撒網(wǎng) - 不僅包括精確匹配了用戶搜索詞條的文檔,還包括了那些我們認(rèn)為和查詢相關(guān)的文檔。如果一個(gè)用戶搜索了"quick brown fox",一份含有fast foxes的文檔也可以作為一個(gè)合理的返回結(jié)果。
如果我們擁有的相關(guān)文檔僅僅是含有fast foxes的文檔,那么它會(huì)出現(xiàn)在結(jié)果列表的頂部。但是如果我們有100份含有quick brown fox的文檔,那么含有fast foxes的文檔的相關(guān)性就會(huì)變低,我們希望它出現(xiàn)在結(jié)果列表的后面。在包含了許多可能的匹配后,我們需要確保相關(guān)度高的文檔出現(xiàn)在頂部。
一個(gè)用來調(diào)優(yōu)全文搜索相關(guān)性的常用技術(shù)是將同樣的文本以多種方式索引,每一種索引方式都提供了不同相關(guān)度的信號(hào)(Signal)。主要字段(Main field)中含有的詞條的形式是最寬泛的(Broadest-matching),用來盡可能多的匹配文檔。比如,我們可以這樣做:
- 使用一個(gè)詞干提取器來將jumps,jumping和jumped索引成它們的詞根:jump。然后當(dāng)用戶搜索的是jumped時(shí),我們?nèi)匀荒軌蚱ヅ浜衘umping的文檔。
- 包含同義詞,比如jump,leap和hop。
- 移除變音符號(hào)或者聲調(diào)符號(hào):比如,ésta,está和esta都會(huì)以esta被索引。
但是,如果我們有兩份文檔,其中之一含有jumped,而另一份含有jumping,那么用戶會(huì)希望第一份文檔的排序會(huì)靠前,因?yàn)樗杏脩糨斎氲木_值。
我們可以通過將相同的文本索引到其它字段來提供更加精確的匹配。一個(gè)字段可以包含未被提取詞干的版本,另一個(gè)則是含有變音符號(hào)的原始單詞,然后第三個(gè)使用了shingles,用來提供和單詞鄰近度相關(guān)的信息。這些其它字段扮演的角色就是信號(hào)(Signals),它們用來增加每個(gè)匹配文檔的相關(guān)度分值。能夠匹配的字段越多,相關(guān)度就越高。
如果一份文檔能夠匹配具有最寬泛形式的主要字段(Main field),那么它就會(huì)被包含到結(jié)果列表中。如果它同時(shí)也匹配了信號(hào)字段,它會(huì)得到一些額外的分值用來將它移動(dòng)到結(jié)果列表的前面。
我們會(huì)在本書的后面討論同義詞,單詞鄰近度,部分匹配以及其他可能的信號(hào),但是我們會(huì)使用提取了詞干和未提取詞干的字段的簡單例子來解釋這個(gè)技術(shù)。
多字段映射(Multifield Mapping)
第一件事就是將我們的字段索引兩次:一次是提取了詞干的形式,一次是未提取詞干的形式。為了實(shí)現(xiàn)它,我們會(huì)使用多字段(Multifields):
1 DELETE /my_index 2 3 PUT /my_index 4 { 5 "settings": { "number_of_shards": 1 }, 6 "mappings": { 7 "my_type": { 8 "properties": { 9 "title": { 10 "type": "string", 11 "analyzer": "english", 12 "fields": { 13 "std": { 14 "type": "string", 15 "analyzer": "standard" 16 } 17 } 18 } 19 } 20 } 21 } 22 }title字段使用了english解析器進(jìn)行詞干提取。 title.std字段則使用的是standard解析器,因此它沒有進(jìn)行詞干提取。
下一步,我們會(huì)索引一些文檔:
1 PUT /my_index/my_type/1 2 { "title": "My rabbit jumps" } 3 4 PUT /my_index/my_type/2 5 { "title": "Jumping jack rabbits" }以下是一個(gè)簡單的針對title字段的match查詢,它查詢jumping rabbits:
1 GET /my_index/_search 2 { 3 "query": { 4 "match": { 5 "title": "jumping rabbits" 6 } 7 } 8 }它會(huì)變成一個(gè)針對兩個(gè)提干后的詞條jump和rabbit的查詢,這要得益于english解析器。兩份文檔的title字段都包含了以上兩個(gè)詞條,因此兩份文檔的分值是相同的:
1 { 2 "hits": [ 3 { 4 "_id": "1", 5 "_score": 0.42039964, 6 "_source": { 7 "title": "My rabbit jumps" 8 } 9 }, 10 { 11 "_id": "2", 12 "_score": 0.42039964, 13 "_source": { 14 "title": "Jumping jack rabbits" 15 } 16 } 17 ] 18 }如果我們只查詢title.std字段,那么只有文檔2會(huì)匹配。但是,當(dāng)我們查詢兩個(gè)字段并將它們的分值通過bool查詢進(jìn)行合并的話,兩份文檔都能夠匹配(title字段也匹配了),而文檔2的分值會(huì)更高一些(匹配了title.std字段):
1 GET /my_index/_search 2 { 3 "query": { 4 "multi_match": { 5 "query": "jumping rabbits", 6 "type": "most_fields", 7 "fields": [ "title", "title.std" ] 8 } 9 } 10 }在上述查詢中,由于我們想合并所有匹配字段的分值,因此使用的類型為most_fields。這會(huì)讓multi_match查詢將針對兩個(gè)字段的查詢子句包含在一個(gè)bool查詢中,而不是包含在一個(gè)dis_max查詢中。
1 { 2 "hits": [ 3 { 4 "_id": "2", 5 "_score": 0.8226396, 6 "_source": { 7 "title": "Jumping jack rabbits" 8 } 9 }, 10 { 11 "_id": "1", 12 "_score": 0.10741998, 13 "_source": { 14 "title": "My rabbit jumps" 15 } 16 } 17 ] 18 }此時(shí),文檔2的分值比文檔1的高許多。
我們使用了擁有寬泛形式的title字段來匹配盡可能多的文檔 - 來增加召回率(Recall),同時(shí)也使用了title.std字段作為信號(hào)來讓最相關(guān)的文檔能夠擁有更靠前的排序(譯注:增加了準(zhǔn)確率(Precision))。
每個(gè)字段對最終分值的貢獻(xiàn)可以通過指定boost值進(jìn)行控制。比如,我們可以提升title字段來讓該字段更加重要,這也減小了其它信號(hào)字段的影響:
1 GET /my_index/_search 2 { 3 "query": { 4 "multi_match": { 5 "query": "jumping rabbits", 6 "type": "most_fields", 7 "fields": [ "title^10", "title.std" ] 8 } 9 } 10 }?
?
from:http://blog.csdn.net/dm_vincent/article/details/41842691
總結(jié)
以上是生活随笔為你收集整理的[Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汉文博士 0.5.6 正式版发布
- 下一篇: 初次使用mybatis Generato