引言:ik分词器的分词范围不够广泛。某些特定行业的专业用语分词能力就不够了,此时就需要自定义分词,与停顿词。
1、下载ik分词器源码
git地址:https://github.com/medcl/elasticsearch-analysis-ik/releases?page=2
下载对应的elasticsearch版本。以7.17.3为例子。下载源码后在idea中打开
2、创建对应数据表
分词表、停止词表。需要字段id,word
3、修改pom文件
修改成对应的elasticsearch的版本号
4、添加mysql依赖
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version>
</dependency>
5、创建数据库配置文件jdbc-reload.properties,放在IK项目的config文件夹下
jdbc.url=jdbc:mysql://192.168.101.109:3306/user_test?serverTimezone=UTC
jdbc.user=root
jdbc.password=123456
jdbc.reload.extend.sql=select word from es_extend_word
jdbc.reload.stop.sql=select word from es_stop_word
# 间隔时间 毫秒
jdbc.reload.interval=1000
6、IK分词器加载分词的源码在witea.analyzer.dic.Dictionary类中,打开这个类,添加如下方法
两个加载分词的方法可以模仿自带的加载分词方法来写,具体如下:
添加加载拓展词方法
/*** 加载自定义数据库拓展词典到主词库表* 55555 20211216*/public void loadExtendDictFromMysql(){Connection connection = null;Statement statement = null;ResultSet resultSet = null;try{Path file = PathUtils.get(getDictRoot(),"jdbc-reload.properties");props.load(new FileInputStream(file.toFile()));logger.info("loading jdbc-reload.properties");for (Object key : props.keySet()) {logger.info(key + "=" + props.getProperty(String.valueOf(key)));}logger.info(" hot dict " + props.getProperty("jdbc.reload.extend.sql"));connection = DriverManager.getConnection(props.getProperty("jdbc.url"),props.getProperty("jdbc.user"),props.getProperty("jdbc.password"));statement = connection.createStatement();resultSet = statement.executeQuery(props.getProperty("jdbc.reload.extend.sql"));while (resultSet.next()){// 加载扩展词典数据到主内存词典中String theWord = resultSet.getString("word");logger.info(theWord);_MainDict.fillSegment(theWord.trim().toLowerCase().toCharArray());}// 加载时间Thread.sleep(Integer.valueOf(String.valueOf(props.get("jdbc.reload.interval"))));}catch (Exception e){logger.error("[Extend Dict Loading] "+ e);}finally {if(resultSet != null){try {statement.close();} catch (SQLException e) {logger.error("[Extend Dict Loading] " + e);}}if(connection != null){try {connection.close();} catch (SQLException e) {logger.error("[Extend Dict Loading] " + e);}}}}
添加加载停用词方法
/*** 加载自定义数据库拓展停止词词典到主词库表* 55555 20211216*/public void loadStopDictFromMysql(){// 建立主词典实例_StopWords = new DictSegment((char) 0);Connection connection = null;Statement statement = null;ResultSet resultSet = null;try{Path file = PathUtils.get(getDictRoot(),"jdbc-reload.properties");props.load(new FileInputStream(file.toFile()));logger.info("loading jdbc-reload.properties");for (Object key : props.keySet()) {logger.info(key + "=" + props.getProperty(String.valueOf(key)));}logger.info(" stop dict " + props.getProperty("jdbc.reload.stop.sql"));connection = DriverManager.getConnection(props.getProperty("jdbc.url"),props.getProperty("jdbc.user"),props.getProperty("jdbc.password"));statement = connection.createStatement();resultSet = statement.executeQuery(props.getProperty("jdbc.reload.stop.sql"));while (resultSet.next()){// 加载扩展词典数据到主内存词典中String theWord = resultSet.getString("word");logger.info(theWord);_StopWords.fillSegment(theWord.trim().toLowerCase().toCharArray());}// 加载时间Thread.sleep(Integer.valueOf(String.valueOf(props.get("jdbc.reload.interval"))));}catch (Exception e){logger.error("[Stop Dict Loading] "+ e);}finally {if(resultSet != null){try {statement.close();} catch (SQLException e) {logger.error("[Stop Dict Loading] " + e);}}if(connection != null){try {connection.close();} catch (SQLException e) {logger.error("[Stop Dict Loading] " + e);}}}}
7、在loadMainDict()中添加自定义的加载拓展词的方法
8、在loadStopWordDict方法中添加自定义的加载停止词的方法
9、因为需要加载数据库,因此需要加载数据库驱动器,在Dictionary中添加:
static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {logger.error("error", e);}}
10、使用maven将项目打包:
注意:这里的版本是否对应elasticsearch的版本
11、将打包好的ik分词器添加到es/plusgins目录下,将原来的ik分词器删除,将新的重新解压并重命名为ik
12、将mysql驱动器jar包添加到ik分词器目录下
/elasticsearch-7.17.3/plugins/ik
13、重启es
1、ps -ef|grep elasticsearch #查看es进程号
2、kill -9 "进程号"
3、cd "es的目录中"
4、bin/elasticsearch -d #后台启动
14、kibana中测试
es7.x版本以上的,可以使用es自带的jdk。用自带的jdk时,会有一个让人头疼的问题。启动会报错,此时需要去添加jdk的权限
grant {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.beans";
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.beans.*";
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.java.swing.plaf.*";
permission java.lang.RuntimePermission "accessClassInPackage.com.apple.*";
permission java.lang.RuntimePermission "setContextClassLoader";
// ip:3306是拓展词数据库ip和端口
permission java.net.SocketPermission "ip:3306","connect,resolve";};
原文:Elastic:IK分词器分词、停用词热更新如何配置(二)基于数据库_wu@55555的博客-CSDN博客