如何開發自己的搜索帝國之安裝ik分詞器
Elasticsearch默認提供的分詞器,會把每個漢字分開,而不是我們想要的根據關鍵詞來分詞,我是中國人 不能簡單的分成一個個字,我們更希望 “中國人”,“中國”,“我”這樣的分詞,這樣我們就需要安裝中文分詞插件,ik就是實現這個功能的。
elasticsearch-analysis-ik 是一款中文的分詞插件,支持自定義詞庫。
現在開始安裝ik分詞器,安裝之前,先說明一些變化:
- 之前可以在node節點上配置index默認的分詞器,如果是多節點,那麽在每個節點上都配置就行了。這個有點不靈活,所以。5.0之後,ES已經不再支持在elasticsearch.yml中配置分詞器,改而在新建索引時,使用settings去配置,這個會在後面的編程中說到。
- 之前使用delete-by-query插件來實現type的整個刪除。這個插件也是從5.0開始沒有了,被整合到了ES的Core中
3.從5.0開始ik的tokenizer發生了變化,提供了兩種,一種為ik_smart,一種為ik_max_word。直接一點,ik_max_word會盡量從輸入中拆分出更多 token,而ik_smart則相反,個人感覺,ik_max_word就是原來的ik,ik_smart是新加的。
下載
有兩種方式,一個是下載源碼自己編譯好後再上傳到ES的插件庫,第二種方法是直接下載編譯好的上傳。
1.源碼安裝
源碼地址:https://github.com/medcl/elasticsearch-analysis-ik,git clone下來。cd elasticsearch-analysis-ik
mvn clean
mvn compile
mvn package
拷貝和解壓release下的文件:
#{project_path}/elasticsearch-analysis-ik/target/releases/elasticsearch-analysis-ik-*.zip 到你的 elasticsearch 插件目錄,
如: plugins/ik 重啟elasticsearch
2.安裝編譯版
直接下載elasticsearch-analysis-ik-5.3.0.zip ,網站地址為:https://github.com/medcl/elasticsearch-analysis-ik/releases 只需要把elasticsearch-analysis-ik-5.3.0.zip解壓,然後拷貝到ES安裝目錄下的plugins文件夾內,並把elasticsearch-analysis-ik-5.3.0文件夾名修改為ik。這樣,就安裝好了。正如前面說的,安裝完插件,現在不需要在配置文件中配置了,需要在新建索引的時候指定分詞器。
重啟啟動ES,可以看到如下log
用kibana查看一下,後續會談到如何這樣做。
至此ES+Kibana+IK安裝好了。從2.4.1到5.X版本號跨度很大,很多地方也發生了很多變化,總體來說,更簡便了。
配置IKAnalyzer.cfg.xml
IKAnalyzer.cfg.xml
在{conf}/analysis-ik/config/IKAnalyzer.cfg.xml
或 {plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml中
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 擴展配置</comment> <!--用戶可以在這裏配置自己的擴展字典 --> <entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry> <!--用戶可以在這裏配置自己的擴展停止詞字典--> <entry key="ext_stopwords">custom/ext_stopword.dic</entry> <!--用戶可以在這裏配置遠程擴展字典 --> <entry key="remote_ext_dict">location</entry> <!--用戶可以在這裏配置遠程擴展停止詞字典--> <entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry> </properties>
熱更新 IK 分詞使用方法
目前該插件支持熱更新 IK 分詞,通過上文在 IK 配置文件中提到的如下配置
<!--用戶可以在這裏配置遠程擴展字典 --> <entry key="remote_ext_dict">location</entry> <!--用戶可以在這裏配置遠程擴展停止詞字典--> <entry key="remote_ext_stopwords">location</entry>
其中 location
是指一個 url,比如 http://yoursite.com/getCustomDict
,該請求只需滿足以下兩點即可完成分詞熱更新。
-
該 http 請求需要返回兩個頭部(header),一個是
Last-Modified
,一個是ETag
,這兩者都是字符串類型,只要有一個發生變化,該插件就會去抓取新的分詞進而更新詞庫。 -
該 http 請求返回的內容格式是一行一個分詞,換行符用
\n
即可。
滿足上面兩點要求就可以實現熱更新分詞了,不需要重啟 ES 實例。
可以將需自動更新的熱詞放在一個 UTF-8 編碼的 .txt 文件裏,放在 nginx 或其他簡易 http server 下,當 .txt 文件修改時,http server 會在客戶端請求該文件時自動返回相應的 Last-Modified 和 ETag。可以另外做一個工具來從業務系統提取相關詞匯,並更新這個 .txt 文件。
官網例子測試
1.創建一個索引
curl -XPUT http://localhost:9200/index
2.創建一個mapping
curl -XPOST http://localhost:9200/index/fulltext/_mapping -d‘ { "properties": { "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } } }‘
3.錄入數據
curl -XPOST http://localhost:9200/index/fulltext/1 -d‘ {"content":"美國留給伊拉克的是個爛攤子嗎"} ‘ curl -XPOST http://localhost:9200/index/fulltext/2 -d‘ {"content":"公安部:各地校車將享最高路權"} ‘ curl -XPOST http://localhost:9200/index/fulltext/3 -d‘ {"content":"中韓漁警沖突調查:韓警平均每天扣1艘中國漁船"} ‘ curl -XPOST http://localhost:9200/index/fulltext/4 -d‘ {"content":"中國駐洛杉磯領事館遭亞裔男子槍擊 嫌犯已自首"} ‘
4.查詢
curl -XPOST http://localhost:9200/index/fulltext/_search -d‘ { "query" : { "match" : { "content" : "中國" }}, "highlight" : { "pre_tags" : ["<tag1>", "<tag2>"], "post_tags" : ["</tag1>", "</tag2>"], "fields" : { "content" : {} } } } ‘
結果
{ "took": 14, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 2, "hits": [ { "_index": "index", "_type": "fulltext", "_id": "4", "_score": 2, "_source": { "content": "中國駐洛杉磯領事館遭亞裔男子槍擊 嫌犯已自首" }, "highlight": { "content": [ "<tag1>中國</tag1>駐洛杉磯領事館遭亞裔男子槍擊 嫌犯已自首 " ] } }, { "_index": "index", "_type": "fulltext", "_id": "3", "_score": 2, "_source": { "content": "中韓漁警沖突調查:韓警平均每天扣1艘中國漁船" }, "highlight": { "content": [ "均每天扣1艘<tag1>中國</tag1>漁船 " ] } } ] } }
參考官方的常見問題
1.自定義詞典為什麽沒有生效?
請確保你的擴展詞典的文本格式為 UTF8 編碼
2.分詞測試失敗 請在某個索引下調用analyze接口測試,而不是直接調用analyze接口 如:http://localhost:9200/your_index/_analyze?text=中華人民共和國MN&tokenizer=my_ik
3.ik_max_word 和 ik_smart 什麽區別?
ik_max_word: 會將文本做最細粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合;
ik_smart: 會做最粗粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,國歌”。
如何開發自己的搜索帝國之安裝ik分詞器