天天看點

ES中使用IK分詞器

之前使用Elasticsearch安裝head插件成功了,但是安裝IK分詞器卻失敗了。貌似是ElasticSearch5.0以後就不支援直接在elasticsearch.yml中配置IK了。原因下面會說明。 

首先下載下傳: 

https://www.elastic.co/downloads/elasticsearch 

https://github.com/medcl/elasticsearch-analysis-ik 

,最新版本貌似是5.3 了。

第一步 預處理:

  1. 解壓elasticsearch-5.3.0.zip>D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0
  2. 解壓elasticsearch-analysis-ik-5.3.0>D:\programfiles\softtools\elasticsearch\plugins\elasticsearch-analysis-ik-5.3.0
  3. 編譯elasticsearch-analysis-ik插件 cmd>D:\programfiles\softtools\elasticsearch\plugins\elasticsearch-analysis-ik-5.3.0>mvn clean package

第二步 配置:

  1. IK配置,如下圖是IK分詞器config目錄下的配置D:\programfiles\softtools\elasticsearch\plugins\elasticsearch-analysis-ik-5.3.0\config 
    ES中使用IK分詞器
  2. 在D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\config目錄中建立ik檔案夾,把上圖中的IK配置檔案放入ElasticSearch目錄中的D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\config\ik目錄下
ES中使用IK分詞器

ik裡面的内容就是 第二步:1.IK配置 裡面的配置。 

3. 配置IK分詞器 

下圖是通過mvn指令編譯後生成的zip包 

ES中使用IK分詞器

将上圖中的zip包放入D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\plugins\ik (ps:ik目錄沒有的話自己建立一個就好),進行解壓 

結果如下圖所示:

ES中使用IK分詞器

整個安裝就完成了。

第三步 測試: 

1. 修改elasticsearch.yml中的配置 

設定cluster.name,node.name,同時解開這兩個配置的注釋 

設定http.port:9200,其他不需要增加配置了 

2. windows下輕按兩下D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\bin\elasticsearch.bat 

不報錯說明安裝成功。 

ES中使用IK分詞器

3. 安裝Http連接配接通路工具,比如火狐插件httpRequester,安裝完成後會在火狐浏覽器右上角出現插件的标示。 

4. 建立索引 

ES中使用IK分詞器
content to send:
{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_smart"
                }
            }
        }
    },
    "mappings" : {
        "logs" : {
            "dynamic" : true,
            "properties" : {
                "message" : {
                    "type" : "string",
                    "analyzer" : "ik_smart"
                }
            }
        }
    }
}
           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

點選Put按鈕,出現圖右邊的傳回值,說明建立索引成功。 

5. 進行分詞測試: 

ES中使用IK分詞器
ES中使用IK分詞器

安裝過程遇到的坑: 

1.将網上對使用IK的配置放到elasticsearch.yml中就會報如下的錯誤: 

org.elasticsearch.bootstrap.StartupException: java.lang.IllegalArgumentException: node settings must not contain any index level settings 

這個無論怎麼想都不明白,而且網上還沒有幾個人遇到過這種情況。

2.Caused by: java.lang.IllegalStateException: jar hell! 

将IK編譯出來的jar,和source.jar兩個檔案放入elasticsearch的lib裡後就出現了,有人說是版本問題,但是我選擇的兩者都是最新版本,并且對應。這裡是因為lib裡面有IK了,然後elasticsearch去讀取plugin檔案夾下的插件的時候又裝載了一次,于是就出現了這個問題。将lib裡的IK jar包删除,改從plugins裡加載就沒有問題了。網上也有不少是這樣做的,但是确實這麼做不正确。 

在D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\logs會看到相應的錯誤日志。 

3. Exception in thread “main” java.lang.IllegalStateException: Could not load plugin descriptor for existing plugin [analysis-ik]. Was the plugin built before 2.0? 

Likely root cause: java.nio.file.NoSuchFileException: /home/es/es2/plugins/analysis-ik/plugin-descriptor.properties 

出現上面的異常是我一開始把編譯出來的jar包放入D:\programfiles\softtools\elasticsearch\elasticsearch-5.3.0\plugins\ik裡面了,其實是要把D:\programfiles\softtools\elasticsearch\plugins\elasticsearch-analysis-ik-5.3.0\target\releases\elasticsearch-analysis-ik-5.3.0.zip解壓到那個ik目錄下面。 

4. 為什麼沒有在elasticsearch.yml配置IK相關的分詞屬性呢 

5. 在github上 https://github.com/medcl/elasticsearch-analysis-ik的使用文檔說了: 

ES中使用IK分詞器

5.0.0及其以後就不會上面兩個分詞器了,而使用兩個參數去替代,同時根據上面的使用文檔來說,作者也沒有說明要針對IK配置elasticsearch.yml。 

總體來說還是遇到一定坎坷的,網上很多ES的文章對于新版本都不适用了。我從新将5.0.0的安裝環境全部删除然後引入最新版本,才搞定了IK分詞器。最新版本的ES安裝head插件應該沒有什麼問題了,畢竟head也沒有要求要對5.0.0以後的版本進行安裝配置的改動。

Install

1.download or compile

download pre-build package from here: https://github.com/medcl/elasticsearch-analysis-ik/releases

or compiled from the source:

checkout ik version respective to your elasticsearch version

git checkout tags/{version}

mvn package

copy and unzip 

target/releases/elasticsearch-analysis-ik-{version}.zip

 to 

your-es-root/plugins/ik

2.restart elasticsearch

Tips:

ik_max_word: 會将文本做最細粒度的拆分,比如會将“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合;

ik_smart: 會做最粗粒度的拆分,比如會将“中華人民共和國國歌”拆分為“中華人民共和國,國歌”。

例如:

GET /_analyze?pretty&analyzer=ik_max_word

{"text":"中華人民共和國"}

Quick Example

1.create a index

curl -XPUT http://localhost:9200/index      

2.create a mapping

curl -XPOST http://localhost:9200/index/fulltext/_mapping -d'
{
    "fulltext": {
             "_all": {
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word",
            "term_vector": "no",
            "store": "false"
        },
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word",
                "include_in_all": "true",
                "boost": 8
            }
        }
    }
}'      

3.index some docs

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.query with highlighting

curl -XPOST http://localhost:9200/index/fulltext/_search  -d'
{
    "query" : { "match" : { "content" : "中國" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}
'      

Result

{
    "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>漁船 "
                    ]
                }
            }
        ]
    }
}      

Dictionary Configuration

IKAnalyzer.cfg.xml

 can be located at 

{conf}/analysis-ik/config/IKAnalyzer.cfg.xml

 or 

{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 檔案。

have fun.

常見問題

1.自定義詞典為什麼沒有生效?

請確定你的擴充詞典的文本格式為 UTF8 編碼

2.如何手動安裝?

git clone https://github.com/medcl/elasticsearch-analysis-ik
cd elasticsearch-analysis-ik
git checkout tags/{version}
mvn clean
mvn compile
mvn package      

拷貝和解壓release下的檔案: #{project_path}/elasticsearch-analysis-ik/target/releases/elasticsearch-analysis-ik-*.zip 到你的 elasticsearch 插件目錄, 如: plugins/ik 重新開機elasticsearch

3.分詞測試失敗 請在某個索引下調用analyze接口測試,而不是直接調用analyze接口 如:http://localhost:9200/your_index/_analyze?text=中華人民共和國MN&tokenizer=my_ik

Changes

5.0.0

  • 移除名為 

    ik

     的analyzer和tokenizer,請分别使用 

    ik_smart

     和 

    ik_max_word

Thanks

YourKit supports IK Analysis for ElasticSearch project with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler.

繼續閱讀