ik中文分词

# 1.什么是ik

  众所周知,es全文搜索依赖索引倒排,简言之,在数据文本存入es之前,es会提取若干文本中的关键字和主键id作对应, 这样,当我们搜索键入的关键字和存入时提取的关键字吻合时,就会返回主键id,然后通过主键id查找整个文本。简单回顾完索引倒排的原理之后 ,回到前提中的问题,什么是ik?ik是针对中文文本提取关键词的插件;
  那为什么需要引入这个ik插件?原理在于中英文语言差异,英文提取可以根据 单词,对于中文来讲就有些水土不服,因为中文需要标点符号内断句和一些人为自定义分词索引的提取;比如我想通过大话搜到大话西游这部电影, 但是在存入es时,es不会智能提取大话作为大话西游整个文本的关键词,所以此时需要人为指定关键词;

# 2.如何使用

  由于本次实验采用docker方式启动的es,所以介绍在docker容器中使用ik插件;使用压缩包方式同理;
  1.下载分词插件,直接在github上搜索ik,点击搜索结果的第一个找到release中对应es版本的zip,然后下载;或者复制链接;
  2.解压插件到安装目录;进入docker容器内部,这里使用docker ps和docker exec命令把插件的zip包复制到容器中/usr/share/elasticsearch/plugins目录下, 创建ik目录,并直接解压安装包的内容到ik目录下(注意不需要安装包名称的目录层级);然后使用elasticsearch-plugin list命令检查插件是否安装解压成功;
  3.配置分词文件;在/usr/share/elasticsearch/plugins/ik/config目录下,找到IKAnalyzer.cfg.xml文件,修改配置remote_ext_dict属性即可,这里采用在线文件方式, 修改可即可生效;
  4.重启es服务;docker-compose restart

<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict"></entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<entry key="remote_ext_dict">http://chenjiwei.cn/ik/ik.txt</entry>
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
1
2
3
4
5
6
7
8
9
10
11

  5.验证自定义分词效果;在kibana的dev-tools中请求,如果ik.txt文件中配置了必有用,则必有用就会单独解析提取;

POST _analyze
{
  "analyzer": "ik_smart",
  "text": "天生你好吗这是"
}
1
2
3
4
5

分词效果

{
  "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
    },
    {
      "token" : "好吗",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "这是",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

可以看到经过配置天生关键词,达到了分词的效果;

# 配置自定义词库文件

  ik自定义词库,采用在服务器上维护一个静态资源文件,然后采用nginx代理的访问方式,因为不想去原来的root目录下新增词库的配置文件, 所以新建一个目录;前面想当然以为在location中重新定义一个root,index即可root指向新目录,index指向ik.txt;发现无效;查询资料后得知可直接使用alias;

location /ik/ik.txt {
    alias /usr/share/nginx/ik/ik.txt;
}
1
2
3

  那么问题又来了为什么指定root不行,root和alias区别在哪里?先回答第一个问题root是可以的,wtf?不得不吐槽还是菜的抠脚,平时配置复制粘贴,root具体的匹配规则 是这样子婶的...
root解析规则

location /root-test/aaa/ {
    root /data/static;
}
1
2
3

当请求http://localhost/root-test/aaa/ik.txt将会返回http://localhost/data/static/root-test/aaa/ik.txt文件;也就是说root规则是寻找root配置(data/static)+匹配location成功所有部分(如root-test/aaa/bbb/test.html)
alias解析规则

location /alias-test/aaa {
    alias /data/static;
}
1
2
3

当请求http://localhost/alias-test/aaa/ik.txt时,服务器会找http://localhost/data/static/ik.txt文件;也就是alias规则,alias配置值+丢掉匹配成功的location部分
  总结来说两者都可以指向静态资源,主要区别在于解析location后面的uri,这使得两者以不同的方式将请求映射到服务器的文件系统;