12、中文分词器IK分词器
TODO
- [ ] 使用mysql热更新词库:补充案例。参考:https://www.cnblogs.com/flower-dance/p/13664064.html
Ik分词器安装使用
介绍
standard 分词器,仅适用于英文。
GET /_analyze
{
"analyzer": "standard",
"text": "中华人民共和国人民大会堂"
}
我们想要的效果是什么:中华人民共和国,人民大会堂
IK分词器就是目前最流行的es中文分词器
安装
官网:https://github.com/medcl/elasticsearch-analysis-ik
下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
根据es版本下载相应版本包。
解压到 es/plugins/ik中,没有ik文件夹新建一个。
重启es。
ik分词器基础知识
ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民大会堂,人民大会,大会堂”,会穷尽各种可能的组合;
ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国,人民大会堂”。
ik分词器的使用
存储时,使用ik_max_word,搜索时,使用ik_smart
PUT /my_index
{
"mappings": {
"properties": {
"text": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
搜索
GET /my_index/_search?q=中华人民共和国人民大会堂
本人测试没有结果
换另一种查询方式
ik配置文件
ik配置文件地址:es/plugins/ik/config目录
IKAnalyzer.cfg.xml
:用来配置自定义词库main.dic
:ik原生内置的中文词库,总共有27万多条,只要是这些单词,都会被分在一起preposition.dic
: 介词quantifier.dic
:放了一些单位相关的词,量词suffix.dic
:放了一些后缀surname.dic
:中国的姓氏stopword.dic
:英文停用词
ik原生最重要的两个配置文件
- main.dic:包含了原生的中文词语,会按照这个里面的词语去分词
- stopword.dic:包含了英文的停用词
停用词,stopword:a the and at but
一般,像停用词,会在分词的时候,直接被干掉,不会建立在倒排索引中
自定义词库
自己建立词库:每年都会涌现一些特殊的流行词,网红,蓝瘦香菇,喊麦,鬼畜,一般不会在ik的原生词典里
- 自己补充自己的最新的词语,到ik的词库里面
- IKAnalyzer.cfg.xml:ext_dict,创建mydict.dic。
- 补充自己的词语,然后需要重启es,才能生效
自己建立停用词库:比如了,的,啥,么,我们可能并不想去建立索引,让人家搜索
custom/ext_stopword.dic
(自己定义的文件,custom在 ik 插件的 config下的目录),可以补充自己的停用词,然后重启es。
使用mysql热更新词库
热更新
每次都是在es的扩展词典中,手动添加新词语,很坑
- 每次添加完,都要重启es才能生效,非常麻烦
- es是分布式的,可能有数百个节点,你不能每次都一个一个节点上面去修改
es不停机,我们直接在外部某个地方添加新的词语,es中立即热加载到这些新词语
热更新的方案:
- 基于ik分词器原生支持的热更新方案,部署一个web服务器,提供一个http接口,通过modified和tag两个http响应头,来提供词语的热更新
- 修改ik分词器源码,然后手动支持从mysql中每隔一定时间,自动加载新的词库
采用第二种方案。第一种,ik、git社区官方都不建议采用,觉得不太稳定。
步骤
1、下载源码
- Url:https://github.com/medcl/elasticsearch-analysis-ik/releases
- ik分词器,是个标准的java maven工程,直接导入eclipse就可以看到源码
2、修改源码
org.wltea.analyzer.dic.Dictionary
类,160行Dictionary单例类的初始化方法,在这里需要创建一个我们自定义的线程,并且启动它
org.wltea.analyzer.dic.HotDictReloadThread
类:就是死循环,不断调用Dictionary.getSingleton().reLoadMainDict()
,去重新加载词典
Dictionary类,399行:this.loadMySQLExtDict();
加载mymsql字典。
Dictionary类,609行:this.loadMySQLStopwordDict();
加载mysql停用词
config下jdbc-reload.properties
。mysql配置文件
3、mvn package打包代码
target\releases\elasticsearch-analysis-ik-7.3.0.zip
4、解压缩ik压缩包
将mysql驱动jar,放入ik的目录下
5、修改jdbc相关配置
6、重启es
观察日志,日志中就会显示我们打印的那些东西,比如加载了什么配置,加载了什么词语,什么停用词
7、在mysql中添加词库与停用词
8、分词实验,验证热更新生效
GET /_analyze
{
"analyzer": "ik_smart",
"text": "传智播客"
}