IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。
IK分词器3.0的特性如下:
当我们创建索引时,字段使用的是标准分词器,所以在查询的时候时常出现问题。
Standard 标准分词:es默认的,如果是英文按单词切分,并且会转化成小写,如果是中文的话,则按一个词切分。
1、下载地址:Releases · medcl/elasticsearch-analysis-ik · GitHub
注意:下载时一定要下载与当前ES版本一致的分词器版本,免得出现一些其他问题。
2、解压 unzip elasticsearch-analysis-ik-6.8.2.zip -d elasticsearch-analysis-ik-6.8.2,将解压后的elasticsearch-analysis-ik-6.8.2文件夹拷贝到elasticsearch-6.8.2/plugins下,并重命名文件夹为ik。
3、重启es,即可加载ik分词器。
IK提供了两个分词算法ik_smart 和 ik_max_word
- #分词器测试ik_smart
- POST _analyze
- {
- "analyzer":"ik_smart",
- "text":"我是中国人"
- }
结果:
- {
- "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
- },
- {
- "token" : "中国人",
- "start_offset" : 2,
- "end_offset" : 5,
- "type" : "CN_WORD",
- "position" : 2
- }
- ]
- }
- #分词器测试ik_max_word
- POST _analyze
- {
- "analyzer":"ik_max_word",
- "text":"我是中国人"
- }
结果:
- {
- "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
- },
- {
- "token" : "中国人",
- "start_offset" : 2,
- "end_offset" : 5,
- "type" : "CN_WORD",
- "position" : 2
- },
- {
- "token" : "中国",
- "start_offset" : 2,
- "end_offset" : 4,
- "type" : "CN_WORD",
- "position" : 3
- },
- {
- "token" : "国人",
- "start_offset" : 3,
- "end_offset" : 5,
- "type" : "CN_WORD",
- "position" : 4
- }
- ]
- }
通过上面的示例我们也看到了,这种中文的分词效果是ES内置的分词器无法比拟的。那么它是如何做到的呢?不要过于惊讶,因为原理其实非常简单,它是通过索引字典来达到的,这样说可能比较抽象难懂,我们来实际看看ES的plugins/ik/config目录:

看到那些*.dic结尾的文件了吗?其实它就是dictionary(字典)的简写,来实际看看字典内容:如上图。
实际的词汇量是非常巨大的,根本不可能完全收录到字典中。如果有需要,我们完全可以通过在字典文件中增加我们想要的词语来扩展我们自己的分词规则。
示例:
“麻花疼”使用ik_smart、ik_max_word 分词后的结果都是:麻花、疼。
无法分词为一个完整的“麻花疼”,因为ik分词器的词典中没有这个词。示例如下图:
- # 麻花疼 使用ik_smart分词
- GET _analyze
- {
- "analyzer": "ik_smart",
- "text": "麻花疼"
- }
-
- {
- "tokens" : [
- {
- "token" : "麻花",
- "start_offset" : 0,
- "end_offset" : 2,
- "type" : "CN_WORD",
- "position" : 0
- },
- {
- "token" : "疼",
- "start_offset" : 2,
- "end_offset" : 3,
- "type" : "CN_CHAR",
- "position" : 1
- }
- ]
- }
- GET _analyze
- {
- "analyzer": "ik_max_word",
- "text": "麻花疼"
- }
-
- {
- "tokens" : [
- {
- "token" : "麻花",
- "start_offset" : 0,
- "end_offset" : 2,
- "type" : "CN_WORD",
- "position" : 0
- },
- {
- "token" : "疼",
- "start_offset" : 2,
- "end_offset" : 3,
- "type" : "CN_CHAR",
- "position" : 1
- }
- ]
- }
如何将“麻花疼”分词为一个完整的词,需要将其添加到词典中。

在plugins/elasticsearch-analysis-ik-6.8.2/config/config目录下有ik分词配置文件:
- IKAnalyzer.cfg.xml,用来配置自定义的词库
- main.dic,ik原生内置的中文词库,只要是这些单词,都会被分在一起。
- surname.dic,中国的姓氏。
- suffix.dic,特殊(后缀)名词,例如
乡、江、所、省等等。- preposition.dic,中文介词,例如
不、也、了、仍等等。- stopword.dic,英文停用词库,例如
a、an、and、the等。- quantifier.dic,单位名词,如
厘米、件、倍、像素等。- extra开头的文件,是额外的词库。

在新的字段配置文件my_ik.dic中添加新词:“麻花疼”。
注意:词库的编码必须是utf-8。


ES启动控制台中会显示已经读取到自定义字典:

再次查询,该词已经成功识别 。

IKAnalyzer.cfg.xml配置文件中的有如下配置:

其中 words_location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。
Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。\n 即可。满足上面两点要求就可以实现热更新分词了,不需要重启es 。
可以将需自动更新的热词放在一个 UTF-8 编码的 .txt文件里,放在 nginx 或其他简易 http server 下,当 .txt文件修改时,http server 会在客户端请求该文件时自动返回相应的 Last-Modified 和 ETag。可以另外做一个工具来从业务系统提取相关词汇,并更新这个 .txt文件。