1、實戰(zhàn)問題球友提問:我想停用所有純數(shù)字的分詞 , 官網(wǎng)上的這個方法好像對ik分詞器無效! 有沒有什么別的方法啊, chart gpt 說分詞可以用正則匹配 但是測試好像是不行的 我的es版本是 8.5.3。 2、進(jìn)一步溝通后,得到問題最精準(zhǔn)描述我的查詢內(nèi)容可能是:"北京市海淀區(qū)清華園10棟105",ik_smart 中文分詞結(jié)果為:“北京市”、“海淀區(qū)”、“清華園”、“10棟”、105。 用戶期望:只想把分詞后,是純數(shù)字的排除掉。也就是說:期望最終分詞結(jié)果為:“北京市”、“海淀區(qū)”、“清華園”、“10棟”。 更進(jìn)一步說:10棟是個分詞,用戶期望檢索分詞結(jié)果:“10棟”。但是105的意義不大,用戶期望分詞階段把類似“105”的純數(shù)字分詞單元去掉。 3、解決方案探討有沒有現(xiàn)成分詞器可以滿足用戶的需求呢?目前看,沒有! 那怎么辦?只能自定義分詞器。咱們之前講過,自定義分詞器核心就如下圖三部分組成。 三部分含義如下,結(jié)合上面的圖會更好理解。
Character Filter 和 Token Filter 的區(qū)別如下: 它倆在 Elasticsearch 中都是文本預(yù)處理的組件,但它們的處理時機(jī)和目標(biāo)略有不同:
本質(zhì)區(qū)別:Character Filter 針對原始的字符級別進(jìn)行處理,而 Token Filter 針對分詞后的詞項級別進(jìn)行處理。 到此為止,再看用戶的需求,期望分詞后去掉“數(shù)字”。那也就是在分詞后的 Token filter 處理為上乘方案。 Token filter 怎么處理呢?考慮數(shù)字級別統(tǒng)一處理的正則表達(dá)式,數(shù)字的正則為:“^[0-9]+$”。 ^[0-9]+$ 可以被分解為幾個部分來解讀:
所以,整體上,這個正則表達(dá)式的含義是:字符串的開頭到結(jié)尾之間只包含一到多個數(shù)字字符,并且沒有其他任何字符。 例如:
一句話,該正則表達(dá)式基本達(dá)到用戶的需求。 實際實現(xiàn)的時候我們發(fā)現(xiàn),對應(yīng) filter 環(huán)節(jié)的:"pattern_replace-tokenfilter"過濾器。該過濾會實現(xiàn)字符級別的替換,我們可以將正則匹配的數(shù)字替換為某個字符,比如“”空格字符。 但,還沒有達(dá)到要求,空格字符用戶期望是剔除。這時候,我們又得考慮“”空格如何剔除。 查閱 filter 官方文檔知道,有個“analysis-length-tokenfilter”的過濾器,將最小長度設(shè)置為1,就能過濾掉長度為0的空格字符。 自此,方案初步敲定。 4、敲定和初步驗證解決方案經(jīng)過上述的討論。我們分三步走戰(zhàn)略。
在將輸入文本復(fù)雜化處理后,分詞結(jié)果依然能達(dá)到預(yù)期。 5、實操實現(xiàn)自定義分詞有了前面的初步實現(xiàn),自定義分詞就變得容易。
索引定義解讀如下:
上 述配置的主要目的是:創(chuàng)建一個自定義的analyzer,該analyzer可以處理中文文本,將純數(shù)字的token替換為空,并確保分析結(jié)果中不包含空token。 最終結(jié)果如下,達(dá)到預(yù)期效果。 6、小結(jié)當(dāng)傳統(tǒng)默認(rèn)分詞不能達(dá)到我們特定的、復(fù)雜的需求的時候,記得還有一招:自定義分詞。 自定義分詞記住三部分組成后,拆解一下復(fù)雜問題的需求,問題就會迎刃而解。 視頻解讀如下: 歡迎大家關(guān)注下我的視頻號,不定期分享 Elasticsearch 實戰(zhàn)進(jìn)階干貨! 7、參考https://www./guide/en/elasticsearch/reference/current/analysis-overview.html https://www./guide/en/elasticsearch/reference/current/analysis-length-tokenfilter.html https://www./guide/en/elasticsearch/reference/current/analysis-pattern_replace-tokenfilter.html |
|