1、IK分词器简介

        IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。

IK分词器3.0的特性如下:

  • 1)采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。
  • 2)采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。
  • 3)对中英联合支持不是很好,在这方面的处理比较麻烦.需再做一次查询,同时是支持个人词条的优化的词典存储,更小的内存占用。
  • 4)支持用户词典扩展定义。
  • 5)针对Lucene全文检索优化的查询分析器IKQueryParser;采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。

        当我们创建索引时,字段使用的是标准分词器,所以在查询的时候时常出现问题。

        Standard 标准分词:es默认的,如果是英文按单词切分,并且会转化成小写,如果是中文的话,则按一个词切分。

2、ES集成IK分词器

2.1、IK分词器的安装

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分词器。

2.2、IK分词器测试

IK提供了两个分词算法ik_smart 和 ik_max_word

  • ik_smart:为最少切分
  • ik_max_word:为最细粒度划分。

2.2.1、最小切分示例

#分词器测试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
    }
  ]
}

2.2.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
    }
  ]
}

3、IK分词器为何如此智能

        通过上面的示例我们也看到了,这种中文的分词效果是ES内置的分词器无法比拟的。那么它是如何做到的呢?不要过于惊讶,因为原理其实非常简单,它是通过索引字典来达到的,这样说可能比较抽象难懂,我们来实际看看ES的plugins/ik/config目录:

3.1、ik分词器的字典

        看到那些*.dic结尾的文件了吗?其实它就是dictionary(字典)的简写,来实际看看字典内容:如上图。

        实际的词汇量是非常巨大的,根本不可能完全收录到字典中。如果有需要,我们完全可以通过在字典文件中增加我们想要的词语来扩展我们自己的分词规则。

4、扩展ik分词器的字典

示例:

        “麻花疼”使用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
    }
  ]
}

如何将“麻花疼”分词为一个完整的词,需要将其添加到词典中。

4.1、ik分词器的配置文件目录

 在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开头的文件,是额外的词库。

4.2、IKAnalyzer.cfg.xml配置文件

4.3、新增字典配置文件,后缀为dic 

在新的字段配置文件my_ik.dic中添加新词:“麻花疼”。

注意:词库的编码必须是utf-8

 4.4、将新增的配置文件添加到IK字典配置文件中,并重启ES和KIBANA

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

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

4.5、IK插件还支持热更新:

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

 其中 words_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文件。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐