[Elasticsearch] 邻近匹配 (二) - 多值字段,邻近程度与相关度
多值字段(Multivalue Fields)
在多值字段上使用短語匹配會產生古怪的行為:
PUT /my_index/groups/1 {"names": [ "John Abraham", "Lincoln Smith"] }執行一個針對Abraham Lincoln的短語查詢:
GET /my_index/groups/_search {"query": {"match_phrase": {"names": "Abraham Lincoln"}} }令人詫異的是,以上的這份文檔匹配了查詢。
即使Abraham以及Lincoln分屬于name數組的兩個人名中。
發生這個現象的原因在于數組在ES中的索引方式。
當John Abraham被解析時。它產生例如以下信息:
- 位置1:john
- 位置2:abraham
然后當Lincoln Smith被解析時。它產生了:
- 位置3:lincoln
- 位置4:smith
換言之,ES對以上數組分析產生的詞條列表和解析單一字符串John Abraham Lincoln Smith時產生的結果是一樣的。在我們的查詢中。我們查詢鄰接的abraham和lincoln,而這兩個詞條在索引中確實存在而且鄰接,因此查詢匹配了。
幸運的是,有一個簡單的方法來避免這樣的情況。通過position_offset_gap參數,它在字段映射中進行配置:
DELETE /my_index/groups/ PUT /my_index/_mapping/groups {"properties": {"names": {"type": "string","position_offset_gap": 100}} }position_offset_gap設置告訴ES須要為數組中的每一個新元素設置一個偏差值。因此,當我們再索引以上的人名數組時,會產生例如以下的結果:
- 位置1:john
- 位置2:abraham
- 位置103:lincoln
- 位置104:smith
如今我們的短語匹配就無法匹配該文檔了。由于abraham和lincoln之間的距離為100。你必需要加入一個值為100的slop的值才干匹配。
越近越好(Closer is better)
短語查詢(Phrase Query)僅僅是簡單地將不含有精確查詢短語的文檔排除在外,而鄰近查詢(Proximity Query) - 一個slop值大于0的短語查詢 - 會將查詢詞條的鄰近度也考慮到終于的相關度_score中。
通過設置一個像50或100這種高slop值,你能夠排除那些單詞過遠的文檔。可是也給予了那些單詞鄰近的文檔一個更高的分值。
以下針對quick dog的鄰近查詢匹配了含有quick和dog的兩份文檔,可是給與了quick和dog更加鄰近的文檔一個更高的分值:
POST /my_index/my_type/_search {"query": {"match_phrase": {"title": {"query": "quick dog","slop": 50 }}} } {"hits": [{"_id": "3","_score": 0.75, "_source": {"title": "The quick brown fox jumps over the quick dog"}},{"_id": "2","_score": 0.28347334, "_source": {"title": "The quick brown fox jumps over the lazy dog"}}] }
使用鄰近度來提高相關度
雖然鄰近度查詢(Proximity Query)管用,可是全部的詞條都必須出如今文檔的這一要求顯的過于嚴格了。這個問題和我們在全文搜索(Full-Text Search)一章的精度控制(Controlling Precision)一節中討論過的類似:假設7個詞條中有6個匹配了,那么該文檔或許對于用戶而言已經足夠相關了,可是match_phrase查詢會將它排除在外。
相比將鄰近度匹配作為一個絕對的要求。我們能夠將它當做一個信號(Signal) - 作為眾多潛在匹配中的一員,會對每份文檔的終于分值作出貢獻(參考多數字段(Most Fields))。
我們須要將多個查詢的分值累加這一事實表示我們應該使用bool查詢將它們合并。
我們能夠使用一個簡單的match查詢作為一個must子句。該查詢用于決定哪些文檔須要被包括到結果集中。能夠通過minimum_should_match參數來去除長尾(Long tail)。
然后我們以should子句的形式加入很多其它特定查詢。每一個匹配了should子句的文檔都會添加其相關度。
GET /my_index/my_type/_search {"query": {"bool": {"must": {"match": { "title": {"query": "quick brown fox","minimum_should_match": "30%"}}},"should": {"match_phrase": { "title": {"query": "quick brown fox","slop": 50}}}}} }毫無疑問我們能夠向should子句中加入其他的查詢,每一個查詢都用來添加特定類型的相關度。
轉載于:https://www.cnblogs.com/zsychanpin/p/6743593.html
總結
以上是生活随笔為你收集整理的[Elasticsearch] 邻近匹配 (二) - 多值字段,邻近程度与相关度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: codevs 1043 方格取数 20
- 下一篇: 计算机的基础知识1