match_phrase搜不出来,怎么办?
1、問題拋出
某個詞組在Elasitcsearch中的某個document中存在,就一定通過某種匹配方式把它搜出來。?
舉例:
title=公路局正在治理解放大道路面積水問題。
輸入關(guān)鍵詞:道路,能否搜索到這個document呢??
實際應(yīng)用中可能需要:?
1)檢索關(guān)鍵詞”理解”、”解放”、”道路”、“理解放大”,都能搜出這篇文檔。?
2)單個的字拆分“治”、“水”太多干擾,不要被檢索出來。?
3)待檢索的詞不在詞典中,也必須要查到。?
4)待檢索詞只要在原文title或content中出現(xiàn),都要檢索到。?
5)檢索要快,要摒棄wildcard模糊匹配性能問題。
2、問題分析
常用的stand標(biāo)準(zhǔn)分詞,可以滿足要求1)、3)、4)、5)。?
標(biāo)準(zhǔn)分詞器是什么鬼??
標(biāo)準(zhǔn)分析儀是默認(rèn)分析儀,如果沒有指定,則默認(rèn)使用該分詞器。 它提供了基于語法的標(biāo)記,并且適用于大多數(shù)語言。?
對于中文字符串,會逐個漢字分詞。?
標(biāo)準(zhǔn)分詞器的結(jié)果如下:
但,會出現(xiàn)冗余數(shù)據(jù)非常多。?
針對要求2),排除match檢索,排除stand分詞。?
針對要求5),排除wildcard模糊檢索。?
針對要求3)、4),新詞也要被檢索到比如:“聲臨其境”、“孫大剩”等也要能被搜索到。?
針對要求1),采用match_phrase貌似靠譜些。
3、小試牛刀
先使用IK-max-word細(xì)粒度分詞器,結(jié)合match_phrase試一試?
步驟1:定義索引和Mapping
PUT ik_index {"mappings":{"ik_type":{"properties":{"title":{"type":"text","fields":{"ik_my_max":{"type":"text","analyzer":"ik_max_word"},"ik_my_smart":{"type":"text","analyzer":"ik_smart"},"keyword":{"type":"keyword","ignore_above":256}}}}}}}這里,為了驗證分詞,同時使用了ik_smart和ik_max兩種分詞。?
實際開發(fā)中不需要,因為:兩種分詞共存,會導(dǎo)致導(dǎo)入數(shù)據(jù)創(chuàng)建索引的時候,索引會非常大,對磁盤和檢索性能都會有影響。
步驟2:插入文檔
POST ik_index/ik_type/3 {"title":"公路局正在治理解放大道路面積水問題" }步驟3:實施檢索
POST ik_index/ik_type/_search {"profile":"true","query":{"match_phrase":{"title.ik_my_max":"道路"}} }搜索結(jié)果如下:?
無結(jié)果返回。
為什么使用了max_word細(xì)粒度分詞,使用了match_pharse檢索,為什么沒有結(jié)果。?
分析一下:?
細(xì)粒度ik_max_word分詞結(jié)果為:
以上方式,除了可以返回分詞結(jié)果外,還能返回詞所在的位置position。
構(gòu)建索引的時候,道路被拆分為:道路:16,道:17,路:19。(注意中間加了18:路面)
{"token": "路面","start_offset": 11,"end_offset": 13,"type": "CN_WORD","position": 18}而檢索的時候,而道路拆分為: 道路0 道1 路2
match_phrase檢索時候,文檔必須同時滿足以下兩個條件,才能被檢索到:?
1)分詞后所有詞項都出現(xiàn)在該字段中;?
2)字段中的詞項順序要一致。?
位置信息可以被存儲在倒排索引中,因此 match_phrase 查詢這類對詞語位置敏感的查詢, 就可以利用位置信息去匹配包含所有查詢詞項,且各詞項順序也與我們搜索指定一致的文檔,中間不夾雜其他詞項。
為了驗證如上的解釋,新增一篇“道路”相關(guān)的title,檢驗一下:
POST ik_index/ik_type/4 {"title":"黨員干部堅持走馬克思主義道路的重要性" }注意:這時,搜索道路是可以匹配到的。
"hits": {"total": 1,"max_score": 1.9684901,"hits": [{"_index": "ik_index","_type": "ik_type","_id": "4","_score": 1.9684901,"_source": {"title": "黨員干部堅持走馬克思主義道路的重要性"}}]},細(xì)粒度ik_max_word分詞結(jié)果為:
黨員干部, 黨員, 干部, 堅持走, 堅持, 堅, 持, 走馬, 馬克思主義, 馬克思, 馬克, 馬, 克, 思, 主義, 道路, 道, 路, 重要性, 重要, 要性, 性構(gòu)建索引的時候,道路被拆分為:15,16,17位置。?
與檢索的詞項順序是一致的。?
這里解析更詳細(xì):http://t.cn/R8pzw9e
4、match_pharse都搜不出來,還有沒有別的方案?
有,和match_pharse類似,不過match_phrase_prefix支持最后一個term前綴匹配。?
除了把查詢文本的最后一個分詞只做前綴匹配之外,match_phrase_prefix和match_phrase查詢基本一樣,參數(shù) max_expansions 控制最后一個單詞會被重寫成多少個前綴,也就是,控制前綴擴(kuò)展成分詞的數(shù)量,默認(rèn)值是50(官網(wǎng)文檔建議50)。?
擴(kuò)展的前綴數(shù)量越多,找到的文檔數(shù)量就越多;?
如果前綴擴(kuò)展的數(shù)量太少,可能查找不到相應(yīng)的文檔,遺漏數(shù)據(jù)。
經(jīng)驗證: 關(guān)鍵詞”理解”、”解放”、”道路”、“理解放大”,都能搜出這篇文檔。
5、應(yīng)用場景
我們自己開發(fā)搜索引擎的時候,經(jīng)常會出現(xiàn)基于title或者content字段進(jìn)行檢索。?
如果用match檢索,會出現(xiàn)噪音很多的情況;?
如果用match_phrase,會出現(xiàn)某些字段檢索不出來的情況,如上分析的“道路”;?
如果用wildcard,能檢索出來,但又有性能問題的存在。?
這時候,可以考慮下: match_phrase_prefix。
6、小結(jié)
實際開發(fā)中,根據(jù)應(yīng)用場景不同,采用不同的分詞器。?
如果選用ik,建議使用ik_max_word分詞,因為:ik_max_word的分詞結(jié)果包含ik_smart。?
匹配的時候,如果想盡可能的多檢索結(jié)果,考慮使用match;?
如果想盡可能精確的匹配分詞結(jié)果,考慮使用match_phrase;?
如果短語匹配的時候,怕遺漏,考慮使用match_phrase_prefix。
總結(jié)
以上是生活随笔為你收集整理的match_phrase搜不出来,怎么办?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Elasticsearch检索分类详解
- 下一篇: Elasticsearch聚合深入详解—