避免lucene queryparser中文分詞的缺陷【轉(zhuǎn)】
很多人在使用lucene時(shí)會(huì)使用其提供的queryparser分析query。不過(guò),lucene的queryparser從一開(kāi)始到現(xiàn)在都沒(méi)有充分考慮中文等語(yǔ)言的特點(diǎn),使得查詢(xún)中文會(huì)出現(xiàn)讓人不可理解的查不到結(jié)果的情況。這個(gè)bug就是LUCENE-2458。
這 個(gè)問(wèn)題簡(jiǎn)單說(shuō)來(lái)就是,對(duì)于一個(gè)連續(xù)的中文query,queryparser將Analyzer返回的Term序列構(gòu)成了PhraseQuery(也有可 能是MultiPhraseQuery),而PhraseQuery默認(rèn)的匹配規(guī)則是要求Term序列在索引的文檔中完全順序匹配。這對(duì)于英文查詢(xún)來(lái)說(shuō)是 可以接受的,因?yàn)閝ueryparser在分析query時(shí),首先通過(guò)AND、OR、NOT將query進(jìn)行切分(這可以理解為queryparser 的第一層分析,這樣切分后構(gòu)成的TOP Query就是BooleanQuery),然后將切分后的subquery交由Analyzer分析(當(dāng)然這要求是滿(mǎn)足FieldQuery的情況,否 則也可能是RangeQuery、WildcardQuery等),因?yàn)橛⑽膯卧~之間以空格分割,相當(dāng)于OR查詢(xún),所以英文中的subquery就可以理 解是個(gè)短語(yǔ)(比如由多個(gè)連字符連接的短語(yǔ),或者是英文和數(shù)字接合的短語(yǔ),在lucene查詢(xún)語(yǔ)法中,顯示的雙引號(hào)之間的內(nèi)容認(rèn)為是短語(yǔ))。但對(duì)中文來(lái)說(shuō), 如果將subquery分析成PhraseQuery,就很成問(wèn)題。比如subquery是”諾基亞N97“,如果構(gòu)成PhraseQuery,則要求索 引的文檔中必須存在”諾基亞N97“,如果”諾基亞“和”N97“中間有其他詞,就不算匹配。對(duì)于這個(gè)例子,是可以調(diào)整PhraseQuery的 slop參數(shù)來(lái)變相解決,但這種情況,使用AND BooleanQuery更合適,使用BooleanQuery在對(duì)文檔打分上也要比PhraseQuery好很多。而對(duì)于query分詞結(jié)果,也存在一 些TermQuery之間是OR的情況,使用PhraseQuery顯然也不合適。
如LUCENE-2458提到,這個(gè)bug會(huì)在3.1和 4中被修復(fù),修復(fù)方法是,只有顯示通過(guò)雙引號(hào)括起來(lái)的subquery才生成 PhraseQuery,否則可以派生子類(lèi)來(lái)自定義處理。就目前使用來(lái)說(shuō),如果你使用IK做Analyzer,那么它提供的IKQueryParser是 很好的替代方案,它構(gòu)造的就是由AND和OR聯(lián)合的BooleanQuery。但因?yàn)锽ooleanQuery沒(méi)有考慮各個(gè)Term在文檔中的位置關(guān)系, 一味的根據(jù)詞頻計(jì)算得分,檢索效果有時(shí)也不是很好。不知道大家是怎么處理的?我有想到去擴(kuò)展它的Query和Scorer,不過(guò)看起來(lái)有些麻煩,暫且還沒(méi) 精力投入上去。
posted on 2010-09-25 10:35 fox009 閱讀(743) 評(píng)論(1) 編輯 收藏 所屬分類(lèi): 搜索引擎技術(shù)