文章目录
# 实验环境# ik分词器的下载、安装、测试## 安装方法一:使用elasticsearch-plugin 安装## 安装方法二:下载编译好的包进行安装1、下载2、安装3、重启`ElasticSearch`查找es进程杀掉es进程重启es4、测试未使用ik分词器,使用默认分词器效果使用IK分词器之后# ik分词器使用说明## ik的分词模式## 创建索引时设置ik分词# 自定义词库扩展## 问题## 方法1、首先进入es根目录中的plugins文件夹下的ik文件夹,进入config目录,创建mydic.dic文件2、打开IKAnalyzer.cfg.xml文件,将新建的mydic.dic配置其中3、重启ES# 热更新 IK 分词# 示例接口# 测试# 实验环境
操作系统:Ubuntu 18.0.4ElasticSearch版本:7.13.2中文分词分词器IK:elasticsearch-analysis-ik-7.13.2# ik分词器的下载、安装、测试
## 安装方法一:使用elasticsearch-plugin 安装
该方法只支持v5.5.1 之后的版本:
./bin/elasticsearch-plugin install /medcl/elasticsearch-analysis-ik/releases/download/v7.13.2/elasticsearch-analysis-ik-7.13.2.zip
## 安装方法二:下载编译好的包进行安装
1、下载
下载地址:/medcl/elasticsearch-analysis-ik/releases
下载和ES相同版本的IK:
2、安装
因为elasticsearch-analysis-ik-7.13.2.zip
是编译好的包,所以只需将elasticsearch-analysis-ik-7.13.2.zip
解压到es的安装目录的/plugins/ik
下面即可:
unzip -o elasticsearch-analysis-ik-7.13.2.zip -d /usr/share/elasticsearch/plugins/ik
3、重启ElasticSearch
查找es进程
ps -ef | grep elastic
杀掉es进程
kill -9 10713
重启es
进入es
的安装目录的bin
下,执行:
./elasticsearch -d
注意
:如果遇到can not run elasticsearch as root
报错,请查看这篇文章:
/willingtolove/article/details/118398026
4、测试
未使用ik分词器,使用默认分词器效果
POST 127.0.0.1:9200/_analyze{"analyzer":"standard","text":"中国人"}
结果:
{"tokens": [{"token": "中","start_offset": 0,"end_offset": 1,"type": "<IDEOGRAPHIC>","position": 0},{"token": "国","start_offset": 1,"end_offset": 2,"type": "<IDEOGRAPHIC>","position": 1},{"token": "人","start_offset": 2,"end_offset": 3,"type": "<IDEOGRAPHIC>","position": 2}]}
使用IK分词器之后
POST 127.0.0.1:9200/_analyze{"analyzer":"ik_max_word","text":"中国人"}
结果:
{"tokens": [{"token": "中国人","start_offset": 0,"end_offset": 3,"type": "CN_WORD","position": 0},{"token": "中国","start_offset": 0,"end_offset": 2,"type": "CN_WORD","position": 1},{"token": "国人","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 2}]}
# ik分词器使用说明
## ik的分词模式
ik有两种分词模式:ik_smart
,ik_max_word
ik_smart
:会将文本做最粗粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、国歌」ik_max_word
:k_max_word:会将文本做最细粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国、国歌」,会穷尽各种可能的组合
## 创建索引时设置ik分词
创建users
索引:
PUT 127.0.0.1:9200/users{"settings": {"number_of_shards": 3,"number_of_replicas": 2},"mappings": {"properties": {"name": {"type": "text"},"age": {"type": "integer"},"describe": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"}}}}
从上面的例子中可以看到:
索引users
的describe
字段的analyzer
属性设置为了ik_max_word
,表示插入文档时,将describe
字段按照ik_max_word
做分词,然后插入倒排索引;索引users
的describe
字段的search_analyzer
属性设置为了ik_smart
,表示在查询时,先对要查询的text类型的输入做按照ik_smart
分词,再去倒排索引搜索;
# 自定义词库扩展
## 问题
有时候,我们搜索一些词库中没有的词,那应该是没有结果的;
比如:"达文西"这个text,想通过搜索"文西"搜索出来。
首先看下:"达文西"这个会被分成哪些词?
POST 127.0.0.1:9200/_analyze{"analyzer":"ik_max_word","text":"达文西"}
{"tokens": [{"token": "达文西","start_offset": 0,"end_offset": 3,"type": "CN_WORD","position": 0}]}
从结果中可以看出,只能解析出一个词来,这样的话,搜索"文西"是搜索出来。
## 方法
通过自定义分词词典,来解决该问题。
1、首先进入es根目录中的plugins文件夹下的ik文件夹,进入config目录,创建mydic.dic文件
cd elasticsearch/plugins/ik/configvi custom.dic
将自定义的词写进去:
达文文西
2、打开IKAnalyzer.cfg.xml文件,将新建的mydic.dic配置其中
<properties><comment>IK Analyzer 扩展配置</comment><!--用户可以在这里配置自己的扩展字典 --><entry key="ext_dict">mydic.dic</entry><!--用户可以在这里配置自己的扩展停止词字典--><entry key="ext_stopwords"></entry><!--用户可以在这里配置远程扩展字典 --><!-- <entry key="remote_ext_dict">words_location</entry> --><!--用户可以在这里配置远程扩展停止词字典--><!-- <entry key="remote_ext_stopwords">words_location</entry> --></properties>
如果有多个自定义字典,可以这样配置:
<!--用户可以在这里配置自己的扩展字典 --><entry key="ext_dict">custom/mydict.dic;custom/mydict1.dic</entry>
3、重启ES
重启后测试:
POST 127.0.0.1:9200/_analyze{"analyzer":"ik_max_word","text":"达文西"}
{"tokens": [{"token": "达文西","start_offset": 0,"end_offset": 3,"type": "CN_WORD","position": 0},{"token": "达文","start_offset": 0,"end_offset": 2,"type": "CN_WORD","position": 1},{"token": "文西","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 2}]}
从结果中可以看到,"达文西"的被分词为:「达文西、达文、文西」三个词。说明自定义分词词典生效。
# 热更新 IK 分词
目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中的如下配置:
<!--用户可以在这里配置远程扩展字典 --><entry key="remote_ext_dict">location</entry><!--用户可以在这里配置远程扩展停止词字典--><entry key="remote_ext_stopwords">location</entry>
其中location
是指一个url
,比如 /getCustomDict,该请求只需满足以下两点即可完成分词热更新。
该http
请求需要返回两个头部(header)
,一个是Last-Modified
,一个是ETag
,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
该 http 请求返回的内容格式是一行一个分词,换行符用\n
即可。
满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。
es-ik
插件源码关于热更新的逻辑:
# 示例接口
[HttpHead("HotUpdate"), HttpPost("HotUpdate"), HttpGet("HotUpdate")]public IActionResult GetHotUpdateDic(){Response.Headers.Add("Last-Modified", DateTime.Now.Ticks.ToString());Response.Headers.Add("ETag", DateTime.Now.Ticks.ToString());return Content("达尔\r\n尔文\r\n丽莎");}
# 测试
在没有配置热更新ik
词库时:
POST 127.0.0.1:9200/_analyze{"analyzer":"ik_max_word","text":"娜丽莎"}
{"tokens": [{"token": "娜丽莎","start_offset": 0,"end_offset": 3,"type": "CN_WORD","position": 0}]}
配置热更新ik
分词词库:
<!--用户可以在这里配置远程扩展字典 --><entry key="remote_ext_dict">http://192.168.2.95:1660/api/fulltextsearch/HotUpdate</entry><!--用户可以在这里配置远程扩展停止词字典--><entry key="remote_ext_stopwords">http://192.168.2.95:1660/api/fulltextsearch/HotUpdateEnd</entry>
配置热更新ik
分词词库一分钟后,测试:
POST 127.0.0.1:9200/_analyze{"analyzer":"ik_max_word","text":"娜丽莎"}
{"tokens": [{"token": "娜丽莎","start_offset": 0,"end_offset": 3,"type": "CN_WORD","position": 0},{"token": "丽莎","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 1}]}
从测试结果中可以看出,「娜丽莎」的分词结果「娜丽莎、丽莎」,说明热更新已生效。