IK分词器虽然自带词库
![](https://img-blog.csdnimg.cn/img_convert/8cb08758b7e55dd65748ea034e1a2238.png)
但是在实际开发应用中对于词库的灵活度的要求是远远不够的,IK分词器虽然配置文件中能添加扩展词库,但是需要重启ES
这章就当写一篇扩展了
其实IK本身是支持热更新词库的,但是需要我感觉不是很好
词库热更新方案:
1:IK 原生的热更新方案,部署一个WEB服务器,提供一个Http接口,通过Modified和tag两个Http响应头,来完成词库的热更新
2:通过修改IK源码支持Mysql定时更新数据
注意:推荐使用第二种方案,也是比较常用的方式,虽然第一种是官方提供的,但是官方也不建议使用
方案一:IK原生方案
1:外挂词库,就是在IK配置文件中添加扩展词库文件多个之间使用分号分割
优点:编辑指定词库文件,部署比较方便
缺点:每次编辑更新后都需要重启ES
2:远程词库,就是在IK配置文件中配置一个Http请求,可以是.dic文件,也可以是接口,同样多个之间使用分号分割
优点:指定静态文件,或者接口设置词库实现热更新词库,不用重启ES,是IK原生自带的
缺点:需要通过Modified和tag两个Http响应头,来提供词库的热更新,有时候会不生效
具体使用就不说了,在这里具体说第二种方案
方案二:通过定时读取Mysql完成词库的热更新
首先要下载IK分词器的源码
网址:https://github.com/medcl/elasticsearch-analysis-ik
下载的时候一定要选对版本,保持和ES的版本一致,否则会启动的时候报错,版本不一致
接着把源码导入IDEA中,并在POM.xml中添加Mysql的依赖,根据自己的Mysql版本需要添加
我的Mysql是5.6.1所以添加5的驱动包
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
然后再config目录下创建一个新的.properties配置文件
![](https://img-blog.csdnimg.cn/img_convert/7c84e33ee9370313028303388fc5c731.png)
在里面配置Mysql的一些配置,以及我们需要的配置
jdbc.url=jdbc:mysql://192.168.43.154:3306/es?characterEncoding=UTF-8&serverTimezone=GMT&nullCatalogMeansCurrent=true
jdbc.user=root
jdbc.password=root
# 更新词库
jdbc.reload.sql=select word from hot_words
# 更新停用词词库
jdbc.reload.stopword.sql=select stopword as word from hot_stopwords
# 重新拉取时间间隔
jdbc.reload.interval=5000
创建一个新的线程,用于调用Dictionary得reLoadMainDict()方法重新加载词库
![](https://img-blog.csdnimg.cn/img_convert/bfc913faf211c36262be1328670def69.png)
package org.wltea.analyzer.dic;
import org.wltea.analyzer.help.ESPluginLoggerFactory;
public class HotDicReloadThread implements Runnable{
private static final org.apache.logging.log4j.Logger logger = ESPluginLoggerFactory.getLogger(Dictionary.class.getName());
@Override
public void run() {
while (true){
logger.info("-------重新加载mysql词典--------");
Dictionary.getSingleton().reLoadMainDict();
}
}
}
修改org.wltea.analyzer.dic文件夹下的Dictionary
在Dictionary类中加载mysql驱动类
private static Properties prop = new Properties();
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
logg