1. 程式人生 > >如何開發自己的搜索帝國之安裝ik分詞器

如何開發自己的搜索帝國之安裝ik分詞器

style utf-8 編碼 ref 文本 需要 shell pack 用戶 you

   Elasticsearch默認提供的分詞器,會把每個漢字分開,而不是我們想要的根據關鍵詞來分詞,我是中國人 不能簡單的分成一個個字,我們更希望 “中國人”,“中國”,“我”這樣的分詞,這樣我們就需要安裝中文分詞插件,ik就是實現這個功能的。

  elasticsearch-analysis-ik 是一款中文的分詞插件,支持自定義詞庫。

  現在開始安裝ik分詞器,安裝之前,先說明一些變化:

  1. 之前可以在node節點上配置index默認的分詞器,如果是多節點,那麽在每個節點上都配置就行了。這個有點不靈活,所以。5.0之後,ES已經不再支持在elasticsearch.yml中配置分詞器,改而在新建索引時,使用settings去配置,這個會在後面的編程中說到。
  2. 之前使用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,該請求只需滿足以下兩點即可完成分詞熱更新。

  1. 該 http 請求需要返回兩個頭部(header),一個是 Last-Modified,一個是 ETag,這兩者都是字符串類型,只要有一個發生變化,該插件就會去抓取新的分詞進而更新詞庫。

  2. 該 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分詞器