elasticsearch修改Ik分词器源码实现基于MySQL更新分词

news/2024/12/24 11:21:27/文章来源:https://www.cnblogs.com/xieshuang/p/18626989

本文主要记录如何修改Ik分词器源码来实现基于MySQL数据库更新分词,所有步骤均为本人实际操作验证。如果你也刚好刷到这篇文章,希望对你有所帮助。
使用过Ik分词器的应该都知道,它提供了三种配置热词词库的方式:

  1. Ik内置词库
  2. Ik外置静态词库
  3. Ik远程词库
    具体可以去看Ik的配置文件,这里不展开说明。通过对源码中定时更新远程词库的阅读,这里采用同样的方式来定时从MySQL数据库获取分词词库。
1. 下载源码

从官网代码库获取跟自己安装的Elasticsearch对应的tag版本,下载地址,这里我选择的是7.9.3版本。
这里我们重点目标是org.wltea.analyzer.dic.Dictionary这是它的词典管理类。

2. 添加MySQL驱动依赖,配置定义和驱动加载

(1) 在源码pom文件中添加MySQL驱动依赖,如下所示。

 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency>

(2)在config目录添加数据库链接配置文件 jdbc-mysql-dict.properties,文件内容如下:

jdbc.url=jdbc:mysql://127.0.0.1:3306/stop_word?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8
jdbc.user=root
jdbc.password=123456
jdbc.reload.sql=select word from hot_words
jdbc.reload.stopword.sql=select stopword as word from hot_stopwords

(3)在Dictionary类中增加代码加载MySQL驱动

private static Properties prop = new Properties();
static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {logger.error("MySQL驱动加载异常:", e);}
}

(4)创建数据库stop_word并添加两张表hot_words和hot_stopwords

3. 在Dictionary类中增加方法更新词典

更新词典

/*** 更新词典*/
private void loadMySQLStopwordDict() {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {Path file = PathUtils.get(getDictRoot(), "jdbc-loadext.properties");prop.load(new FileInputStream(file.toFile()));logger.info("jdbc-reload.properties");for(Object key : prop.keySet()) {logger.info(key + "=" + prop.getProperty(String.valueOf(key)));}logger.info("query hot stopword dict from mysql, " + prop.getProperty("jdbc.reload.stopword.sql") + "......");conn = DriverManager.getConnection(prop.getProperty("jdbc.url"),prop.getProperty("jdbc.user"),prop.getProperty("jdbc.password"));stmt = conn.createStatement();rs = stmt.executeQuery(prop.getProperty("jdbc.reload.stopword.sql"));while(rs.next()) {String theWord = rs.getString("word");logger.info("hot stopword from mysql: " + theWord);_StopWords.fillSegment(theWord.trim().toCharArray());}} catch (Exception e) {logger.error("erorr", e);} finally {if(rs != null) {try {rs.close();} catch (SQLException e) {logger.error("error", e);}}if(stmt != null) {try {stmt.close();} catch (SQLException e) {logger.error("error", e);}}if(conn != null) {try {conn.close();} catch (SQLException e) {logger.error("error", e);}}}
}

更新停用词

private void loadMySQLStopwordDict() {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {Path file = PathUtils.get(getDictRoot(), "jdbc-loadext.properties");prop.load(new FileInputStream(file.toFile()));logger.info("jdbc-reload.properties");for(Object key : prop.keySet()) {logger.info(key + "=" + prop.getProperty(String.valueOf(key)));}logger.info("query hot stopword dict from mysql, " + prop.getProperty("jdbc.reload.stopword.sql") + "......");conn = DriverManager.getConnection(prop.getProperty("jdbc.url"),prop.getProperty("jdbc.user"),prop.getProperty("jdbc.password"));stmt = conn.createStatement();rs = stmt.executeQuery(prop.getProperty("jdbc.reload.stopword.sql"));while(rs.next()) {String theWord = rs.getString("word");logger.info("hot stopword from mysql: " + theWord);_StopWords.fillSegment(theWord.trim().toCharArray());}} catch (Exception e) {logger.error("erorr", e);} finally {if(rs != null) {try {rs.close();} catch (SQLException e) {logger.error("error", e);}}if(stmt != null) {try {stmt.close();} catch (SQLException e) {logger.error("error", e);}}if(conn != null) {try {conn.close();} catch (SQLException e) {logger.error("error", e);}}}
}

对外暴露方法:

public void reLoadSQLDict() {this.loadMySQLExtDict();this.loadMySQLStopwordDict();
}

增加线程类MySQLDictReloadThread去更新分词:

package org.wltea.analyzer.dic;import org.apache.logging.log4j.Logger;
import org.wltea.analyzer.help.ESPluginLoggerFactory;/*** @description:* @date: 2024/11/29**/
public class MySQLDictReloadThread implements Runnable{private static  final Logger logger = ESPluginLoggerFactory.getLogger(MySQLDictReloadThread.class.getName());@Overridepublic void run() {logger.info("reloading hot_word and stop_word dict from mysql");Dictionary.getSingleton().reLoadSQLDict();}
}

仿照源码,增加定时调度:
在这里插入图片描述

4. 重新打包

这里参照ik源码,修改对应的src/main/assemblies/plugin.xml文件,将MySQL驱动包含进去

<dependencySet><outputDirectory/><useProjectArtifact>true</useProjectArtifact><useTransitiveFiltering>true</useTransitiveFiltering><includes><include>mysql:mysql-connector-java</include></includes>
</dependencySet>

就下来将ik上传到elasticsearch插件目录下,可参照这篇文章elasticsearch安装ik分词器,然后重启es。
这里我遇到一点问题,启动后日志会报错,提示权限不足,这是由于es的启用了Java安全管理器,那么我们去增加对应权限即可。这里我一开始修改的是es安装目录下的/elasticsearch-7.9.3/jdk/conf/security/java.policy文件,结果并没有生效,这里我们去看es的启动脚本,通过日志输出可以很清晰的看到es使用的是本机的Java环境:

[2024-12-02T15:31:49,913][INFO ][o.e.n.Node               ] [node-1] JVM home [/usr/local/java/jdk1.8.0_152/jre]

这里将需要的权限都添加到/usr/local/java/jdk1.8.0_152/jre/lib/security/java.policy文件中:

permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
permission java.util.PropertyPermission "*", "read,write";
permission javax.security.auth.AuthPermission "getSubject";
permission javax.security.auth.AuthPermission "modifyPrincipals";
permission javax.security.auth.AuthPermission "getLoginConfiguration";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "loadLibrary.jaas_unix";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "createSecurityManager";
permission java.lang.RuntimePermission "closeClassLoader";
permission java.net.SocketPermission "127.0.0.1:3306","connect,resolve";

最后添加的那条是为了连接数据库服务器添加的。
至此 我们再次重启es服务,已经能正常运行了。

5. 验证词库效果

这里我们先看一下未添加词库前的
在这里插入图片描述
往数据库插入两个词 恰斯卡和纳塔,从日志可以看出已经加载进去了:
在这里插入图片描述
再来看一下效果:
在这里插入图片描述
功能基本实现,这是一个demo,在实际使用中可以在此基础再做进一步的扩展。ok本文到此结束。谢谢阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/858039.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从家电的“大成”到汽车的“认怂”,苏峻的工业设计追梦之路

孕育三年八个月,iCAR V23是苏峻进入汽车产业的第一个“孩子”,12月16日带着明星气质呱呱落地。 很巧,苏峻的上一个创业项目——米家空气净化器,落地正好十周年。和净化器一经面试即大成相比,iCAR V23上市后,苏峻的第一次发声,却是认错的内容——V23上市后,第一时间听取…

Vue2环境中AntDeisgn1.x的树形下拉选择组件

示例相关代码 <a-tree-selectv-model="type"show-searchstyle="width: 100%":dropdown-style="{ maxHeight: 400px, overflow: auto }"placeholder="请选择"allow-clear:tree-data="treeData":filter-tree-node="fi…

Linux 虚拟机重启找不到IP解决方案

@目录前言简介Linux 操作系统查看不到IP地址问题描述:第一步 :修改配置第二步 :查看ip第三步 :查看网卡第四步 :重启网络‌Linux 网络服务重启失败解决办法问题描述:第一步:查看NetworkManager的状态第二步:停止NetworkManager第三步:重启Network第四步:禁用NetworkM…

浏览器连续循环数据打印分页时分割模块问题

css设置@media print识别打印容器,给独立块元素(不想被分割的class添加 page-break-inside: avoid; 避免在元素内部进行分页 ),如下: -- 这样遇到一页纸不够放的时候不会分割 print-wrap 这个元素,自动换行到下一页~ @media print { .printChild { width: 100%;…

BERT的继任者ModernBERT:融合长序列处理、代码理解与高效计算的新一代双向编码器

BERT 发布于 2018 年(从人工智能发展速度来看已是遥远的过去),但它至今仍在广泛使用:实际上它目前是 HuggingFace hub 上下载量第二高的模型,月下载量超过 6800 万次,仅次于另一个针对检索任务优化的编码器模型。这源于其编码器架构在处理日常实际问题方面表现出色,例如…

OpenHarmony怎么修改DPI密度值?触觉智能RK3566鸿蒙开发板演示

开源鸿蒙OpenHarmony系统下,修改DPI密度值的方法,触觉智能Purple Pi OH鸿蒙开发板演示,搭载了瑞芯微RK3566四核处理器,Laval鸿蒙社区推荐开发板,已适配全新开源鸿蒙OpenHarmony5.0 Release系统,适合鸿蒙开发入门学习本文介绍在开源鸿蒙OpenHarmony系统下,修改DPI密度值的…

医疗行业的项目管理革新:提升工作效率与患者体验

一、医疗行业的痛点 医疗行业在日常运营中面临一系列管理和运营上的挑战,以下是一些主要痛点: 1.任务管理与进度跟踪困难 在医院或医疗机构中,医疗任务和工作往往涉及多个科室、医护人员和患者。传统的管理方式通常依赖纸质记录或简单的电子表格,这种方法在任务繁多、协作复…

实战案例:基于 Java Web 技术的医药信息管理系统设计与构建

1. 引言 1.1系统目标 本医药信息管理系统旨在实现药品信息、进货信息、销售信息、库存信息、处方信息以及员工信息等的全面管理,提高医药企业运营效率,优化业务流程,确保信息准确、及时、安全,为企业决策提供有力支持,同时提升服务质量,增强企业竞争力。 1.2适用范围 本系…

CentOS安装GitLab社区版

官方文档给出的下载链接,貌似下不动。 因此选择使用清华大学的镜像站来下载社区版的GitLab https://mirror.tuna.tsinghua.edu.cn/help/gitlab-ce/ 于/etc/gitlab/gitlab.rb配置文件处,修改你的GitLab访问地址 默认GitLab访问地址是:external_url http://gitlab.example.c…

微信小程序云开发 校园二手交易平台

1.组员分工 在这个校园二手交易平台小程序中,我们组有着非常明细的分工。组内一共有四人,分别是祝辰、林炜辰、秦盼盼、吕冠逾,接下来我会一一描述分工。 祝辰:第七组的组长,主要整个软件项目工程的进度协调。在软件项目初期,主要负责用户图、类图、书序图的绘制,明确项…

冬季双旦节,宠物行业市场部用啥办公软件最佳?

随着冬季双旦节的临近,宠物行业迎来了业务的高峰期。在这个关键时期,仓储物流环节的高效运作对于满足宠物用品市场需求、提升客户满意度以及实现企业业绩增长起着举足轻重的作用。合适的可视化团队协作办公软件能够助力宠物公司更好地管理仓储物流,精准调配资源。本文将为宠…