elasticsearch 虽然自带默认词库,但是在实际应用中对于词库灵活度的要求还是远远达不到的,elasticsearch 支持我们自定义词库,此文章就来讲一讲如何又快又好地对词库进行热更新
热更新方案
1.基于ik分词器原生的热更新方案,部署一个web服务器,提供一个http接口,通过modified和tag两个http响应头,来提供词语的热更新
2.通过修改源码支持mysql定时拉取数据更新
推荐使用第二种方式,也是比较常用的方式,虽然前第二种方式是官方方法,但是官方也不支持使用
方案
1.ik分词器原生方案
外置静态词库
优点:编辑指定分词文件即可,部署比较方便
缺点:每次编辑之后都需要重启elasticsearch服务才能生效
远程词库:
优点:指定静态文件代理服务器设置词库
缺点:需要通过modified和tag两个http响应头,来提供词语的热更新,有时候会不生效
使用方法
进入config文件夹下
选择IKAnalyzer.cfg.xml 文件
IK Analyzer 扩展配置
community.dic
ext_dict(词库) 和 ext_stopwords(停止词库) 需要将文件放在config文件夹下才会生效,每次更新词库之后需要重启es;
remote_ext_dict 和 remote_ext_stopwords 需要将文件放在静态服务器上,默认拉取时间间隔为 一分钟
/**
* 词典初始化 由于IK Analyzer的词典采用Dictionary类的静态方法进行词典初始化
* 只有当Dictionary类被实际调用时,才会开始载入词典, 这将延长首次分词操作的时间 该方法提供了一个在应用加载阶段就初始化字典的手段
*
* @return Dictionary
*/
public static synchronized Dictionary initial(Configuration cfg) {
if (singleton == null) {
synchronized (Dictionary.class) {
if (singleton == null) {
singleton = new Dictionary(cfg);
singleton.loadMainDict();
singleton.loadSurnameDict();
singleton.loadQuantifierDict();
singleton.loadSuffixDict();
singleton.loadPrepDict();
singleton.loadStopWordDict();
// 执行更新词库的线程
new Thread(new HotDicReloadThread()).start();
if(cfg.isEnableRemoteDict()){
// 建立监控线程
for (String location : singleton.getRemoteExtDictionarys()) {
// 10 秒是初始延迟可以修改的 60是间隔时间 单位秒
pool.scheduleAtFixedRate(new Monitor(location), 10, 60, TimeUnit.SECONDS);
}
for (String location : singleton.getRemoteExtStopWordDictionarys()) {
pool.scheduleAtFixedRate(new Monitor(location), 10, 60, TimeUnit.SECONDS);
}
}
return singleton;
}
}
}
return singleton;
}
2.通过mysql热更新词库
首先拉取ik分词器源码,源码传送门请点击这里
既然要使用mysql更新,就要先引入maven
mysql
mysql-connector-java
6.0.6
在config 文件夹下创建一个新的.properties文件jdbc-reload.properties
jdbc.url=jdbc:mysql://192.168.10.200:3316/platform_foreign_website?characterEncoding=UTF-8&serverTimezone=GMT&nullCatalogMeansCurrent=true
jdbc.user=dbadmin_app
jdbc.password=dap12345678@
# 更新词库
jdbc.reload.sql=select word from hot_words
# 更新停用词词库
jdbc.reload.stopword.sql=select stopword as word from hot_stopwords
# 重新拉取时间间隔
jdbc.reload.interval=5000