本文所使用的ES集群環(huán)境可在歷史文章中獲取,采用docker部署的方式察纯。
Elasticsearch 是一個功能強(qiáng)大的搜索引擎,廣泛用于構(gòu)建復(fù)雜的全文搜索應(yīng)用程序。在許多情況下甜攀,為了提高搜索引擎的性能和精度秋泄,我們可以使用外部詞庫來定制和擴(kuò)展 Elasticsearch 的文本處理和搜索功能。本文將介紹外部詞庫的用途规阀、優(yōu)勢以及如何在 Elasticsearch 中使用它們恒序。
為什么需要外部詞庫?
Elasticsearch 默認(rèn)提供了一套強(qiáng)大的文本處理工具谁撼,包括分詞歧胁、標(biāo)記過濾、同義詞處理等厉碟。然而喊巍,在某些情況下,我們需要更多的控制權(quán)來適應(yīng)特定的用例和需求箍鼓。外部詞庫允許我們:
自定義分詞器:通過使用外部詞庫崭参,您可以創(chuàng)建自定義分詞器款咖,以根據(jù)特定需求定義文本分割規(guī)則何暮。這對于處理不同語言或行業(yè)的文本非常有用。
擴(kuò)展停用詞列表:停用詞(如
and
铐殃、the
等)通常被排除在搜索索引之外海洼。外部詞庫允許您將領(lǐng)域特定的停用詞添加到索引中,以便更好地適應(yīng)我們行業(yè)內(nèi)的數(shù)據(jù)富腊。同義詞處理:創(chuàng)建同義詞詞庫可確保相關(guān)詞匯在搜索時被正確映射贰军,提高搜索結(jié)果的準(zhǔn)確性。
專業(yè)術(shù)語:對于特定領(lǐng)域或行業(yè)蟹肘,我們可以通過創(chuàng)建外部詞庫词疼,以包含特定領(lǐng)域的專業(yè)術(shù)語,確保搜索引擎能夠理解和處理這些術(shù)語帘腹。
使用外部詞庫的優(yōu)勢
使用外部詞庫有以下優(yōu)勢:
提高搜索質(zhì)量:通過自定義分詞和停用詞贰盗,可以確保搜索引擎更好地理解和處理文本,提高搜索質(zhì)量阳欲。
適應(yīng)特定需求:外部詞庫允許根據(jù)特定用例和領(lǐng)域需求對搜索引擎進(jìn)行定制舵盈,以滿足工作要求。
更好的用戶體驗(yàn):通過包含專業(yè)術(shù)語和擴(kuò)展的同義詞映射球化,用戶能夠更輕松地找到他們需要的內(nèi)容秽晚。
如何在 Elasticsearch 中使用外部詞庫
在 Elasticsearch 中使用外部詞庫通常涉及以下步驟:
創(chuàng)建外部詞庫文件:首先,我們需要準(zhǔn)備一個外部詞庫文件筒愚,其中包含自定義的詞匯赴蝇、同義詞或停用詞列表。
將詞庫上傳到 Elasticsearch:上傳詞庫文件到 Elasticsearch
配置索引:將外部詞庫與索引相關(guān)聯(lián)巢掺,以確保 Elasticsearch 在索引文檔時使用這些詞匯句伶。
搜索優(yōu)化:根據(jù)需要在搜索查詢中應(yīng)用外部詞庫劲蜻,以擴(kuò)展或定制搜索行為。
示例:使用自定義詞庫分詞
本文在 IK
分詞器的基礎(chǔ)上增加自定義分詞考余,并配置本地詞庫文件先嬉,遠(yuǎn)程熱更新詞庫文件。
本地詞庫
-
首先在啟動的
ES
中對醉魚
兩個字進(jìn)行分詞楚堤,IK
默認(rèn)分為兩個漢字GET _analyze { "analyzer": "ik_max_word", "text": ["醉魚"] }
結(jié)果如下
{ "tokens" : [ { "token" : "醉", "start_offset" : 0, "end_offset" : 1, "type" : "CN_CHAR", "position" : 0 }, { "token" : "魚", "start_offset" : 1, "end_offset" : 2, "type" : "CN_CHAR", "position" : 1 } ] }
而我們的需求是讓其能分為一次詞語疫蔓,而不是兩個漢字,那么下面引入我們的自定義分詞文件
-
在
ES
的plugins/ik/config
目錄下創(chuàng)建自定義詞庫文件zuiyu.dic
,文件內(nèi)容如下,格式為一個詞語為一行淌哟。醉魚
-
修改
IK
的配置,支持自定義分詞文件 拗小,修改plugins/ik/config
目錄下的IKAnalyzer.cfg.xml
重罪,修改其中<entry key="ext_dict"></entry>
的值樱哼,為本地文件路徑,配置為相對路徑剿配,直接填寫上一步創(chuàng)建的zuiyu.dic
搅幅,結(jié)果如下<entry key="ext_dict">zuiyu.dic</entry>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 擴(kuò)展配置</comment> <!--用戶可以在這里配置自己的擴(kuò)展字典 --> <entry key="ext_dict">zuiyu.dic</entry> <!--用戶可以在這里配置自己的擴(kuò)展停止詞字典--> <entry key="ext_stopwords"></entry> <!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 --> <!--<entry key="remote_ext_dict"></entry>--> <!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
-
如果是啟動的
ES
集群,需要復(fù)制當(dāng)前兩個文件到所有的集群中1呼胚、當(dāng)前集群有三個節(jié)點(diǎn)茄唐,其中都配置本地詞庫文件,但是
node1
蝇更,node2
中都沒有增加醉魚
這詞語沪编,只有node3
有,此時使用分詞是無法達(dá)到預(yù)期效果的年扩。2蚁廓、
node1
中配置正常的<entry key="ext_dict">zuiyu.dic</entry>
,zuiyu.dic
中也包含醉魚
這個詞語厨幻。node2
相嵌,node3
都不配置ext_dict
,此時當(dāng)前這個環(huán)境是可以進(jìn)行正確分詞况脆,達(dá)到預(yù)期的結(jié)果的饭宾。 重啟
ES
-
測試分詞效果,使用同樣的分詞語句
GET _analyze { "analyzer": "ik_max_word", "text": ["醉魚"] }
結(jié)果如下
{ "tokens" : [ { "token" : "醉魚", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 } ] }
一般來說格了,詞語肯定不是固定的看铆,隨著工作的長期積累,不斷地發(fā)現(xiàn)新的專業(yè)術(shù)語盛末,那么熱更新性湿,動態(tài)更新詞庫纬傲,不在每次更新詞庫之后重啟
ES
就是非常有必要的了,下面來看一下熱更新詞庫肤频。
遠(yuǎn)程詞庫(熱更新)
熱更新詞庫的區(qū)別就是IKAnalyzer.cfg.xml
文件中的一個配置的問題叹括。不過核心還是需要一個詞庫文件,剛才是通過路徑訪問的宵荒,但是無法熱更新汁雷,所以現(xiàn)在需要改為URL
訪問,也就是 HTTP
請求可以讀取到的形式报咳。一個詞語一行返回即可侠讯。
此處使用 Nginx
來做演示。Nginx
中的配置如下
-
nginx.conf
location /dic/zuiyu.dic { alias html/dic/zuiyu.dic; }
-
zuiyu.dic
文件內(nèi)容如下醉魚
-
IKAnalyzer.cfg.xml
配置修改如下,IP
為部署的Nginx
的IP
暑刃,端口也是根據(jù)自己Nginx
監(jiān)聽的端口修改<entry key="remote_ext_dict">http://192.168.30.240:8088/dic/zuiyu.dic</entry>
完整的配置如下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 擴(kuò)展配置</comment> <!--用戶可以在這里配置自己的擴(kuò)展字典 --> <entry key="ext_dict">zuiyu.dic</entry> <!--用戶可以在這里配置自己的擴(kuò)展停止詞字典--> <entry key="ext_stopwords"></entry> <!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 --> <entry key="remote_ext_dict">http://192.168.30.240:8088/dic/zuiyu.dic</entry> <!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
驗(yàn)證
URL
訪問結(jié)果厢漩,使用瀏覽器或者postman
等工具訪問http://192.168.30.240:8088/dic/zuiyu.dic
可以返回我們的文件內(nèi)容即可,也是一個詞語一行的形式岩臣。復(fù)制
IKAnalyzer.cfg.xml
到集群的每個節(jié)點(diǎn)中重啟
ES
-
測試對
醉魚
分詞溜嗜,可以看到與上面本地詞庫時是同樣的效果{ "tokens" : [ { "token" : "醉魚", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 } ] }
-
測試對
我愛你醉魚
進(jìn)行分詞GET _analyze { "analyzer": "ik_max_word", "text": ["我愛你醉魚"] }
結(jié)果如下
{ "tokens" : [ { "token" : "我愛你", "start_offset" : 0, "end_offset" : 3, "type" : "CN_WORD", "position" : 0 }, { "token" : "愛你", "start_offset" : 1, "end_offset" : 3, "type" : "CN_WORD", "position" : 1 }, { "token" : "醉魚", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 2 } ] }
-
在
zuiyu.dic
中增加我愛你醉魚
,最終的文件內(nèi)容如下醉魚 我愛你醉魚
-
增加完成之后架谎,這5個字已經(jīng)成為一個詞語炸宵,分詞結(jié)果如下
{ "tokens" : [ { "token" : "我愛你醉魚", "start_offset" : 0, "end_offset" : 5, "type" : "CN_WORD", "position" : 0 }, { "token" : "我愛你", "start_offset" : 0, "end_offset" : 3, "type" : "CN_WORD", "position" : 1 }, { "token" : "愛你", "start_offset" : 1, "end_offset" : 3, "type" : "CN_WORD", "position" : 2 }, { "token" : "醉魚", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 3 } ] }
僅在一個節(jié)點(diǎn)
node1
中配置了遠(yuǎn)程詞庫,node2
與node3
都沒有配置任何的詞庫谷扣,此時當(dāng)前環(huán)境無法達(dá)到我們的預(yù)期分詞效果
總結(jié)
通過上面我們的試驗(yàn)土全,可以發(fā)現(xiàn)結(jié)合 IK
分詞器,使用自定義詞庫会涎,可以滿足我們專業(yè)內(nèi)的詞語分詞裹匙,實(shí)現(xiàn)更好的分詞效果,再加上動態(tài)詞庫的更新末秃,對我們的工作還是很有必要的概页,配置過程是不是很簡單,下面就趕緊用起來吧蛔溃。