当前位置: 首页 > news >正文

ES IK分词字典热更新

前言

在使用IK分词器的时候,发现官方默认的分词不满足我们的需求,那么有没有方法可以自定义字典呢?

官方提供了三种方式

一、ik本地文件读取方式

k插件本来已为用户提供自定义词典扩展功能,只要修改配给文件即可:

1、添加自定义词典文件

在es/plugins/ik/config目录下创建mydict.dic文件;
mydict.dic文件中添加自定义热词;

2、修改IKAnalyzer.cfg.xml配置文件

在es/plugins/ik/config目录下修改IKAnalyzer.cfg.xml,修改内容如下:

/custom/mydict.dic

注意:mydict.dic文件格式为UTF-8

二、ik远程词库调用

1、ik官方文档说明

目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

location

location

其中 location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。
1.该 http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
2.该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

2、http接口编写

@GetMapping("/keyWord/hot")public void getHotWordByOracle(HttpServletResponse response, Integer type) throws IOException {//查询分词字典if (type == null) {type = 0;}List<String> keyWords = keyWordDictService.getKeyWord(type);StringBuilder result = new StringBuilder();for (String value : keyWords){result.append(value+"\n");}result.delete(result.length()-1,result.length());try {String time = new Date().toString();response.setHeader("Last-Modified", time);response.setHeader("ETag",time);response.setContentType("text/plain; charset=utf-8");response.setBufferSize(500000);PrintWriter writer = response.getWriter();writer.write(result.toString());} catch (IOException e) {log.error("自定义词典更新报错" , e);}}

接口注意点:需要设置ContentType,根据业务需要BufferSize设置要大,并且不能使用flush

研究一下tomcat的相关特性。

在tomcat当中,是使用一个respone buffer的缓存来存储即将发回的数据,如果这个buffer没有使用完,默认的情况下,tomcat使用的就是常规的方式,就是一次性返回,这个时候在response header当中是有Content-Length。如果这个buffer写满了而你还有数据要歇的时候,这个时候就先要进行一次会写,这个时候tomcat的响应就变成了chuncked的模式了。还有一种情况,如果显示的进行flush操作,就是response.gerWriter wirter.flush也会导致变成chuncked响应。
因此,在springboot tomcat项目中,需要将buffer size设置的更大(具体看自己的业务需求),同时不能显式的去调用flush操作

三、MYSQL实现热更新词库

1、下载源码

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/tree/v7.8.0
IK分词器版本要和ES版本一样

2、修改源码

添加 jdbc-reload.properties 配置文件

jdbc.url=jdbc:mysql://127.0.0.1:3307/test?serverTimezone=GMT
jdbc.user=root
jdbc.password=abc123456
jdbc.reload.sql=select word from hot_words
jdbc.reload.stopword.sql=select stopword as word from hot_stopwords
jdbc.reload.interval=1000

添加热更新线程类 HotDictReloadThread,就是一个死循环,不断调用Dictionary.getSingleton().reLoadMainDict(),去重新加载词典

public class HotDictReloadThread implements Runnable{private static final Logger LOGGER = ESPluginLoggerFactory.getLogger(HotDictReloadThread.class.getName());@Overridepublic void run() {while (true){LOGGER.info("reload hot dict from mysql");Dictionary.getSingleton().reLoadMainDict();}}
}

修改 Dictionary类initial 初始化方法,创建一个我们自定义的线程,并且启动它

new Thread(new  HotDictReloadThread()).start();

在这里插入图片描述
增加从mysql加载扩展词典方法

private static Properties prop = new Properties();static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e){logger.error("error",e);}}/*** 从mysql加载扩展词典*/private void loadMySqlExtDict(){Connection conn = null;Statement stmt = null;ResultSet rs = null;try {Path file = PathUtils.get(getDictRoot(),"jdbc-reload.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 dict from mysql," + prop.getProperty("jdbc.reload.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.sql"));while (rs.next()){String word = rs.getString("word");logger.info("hot word from mysql:" + word);_MainDict.fillSegment(word.trim().toCharArray());}Thread.sleep(Integer.valueOf(String.valueOf(prop.get("jdbc.reload.interval"))));} catch (Exception e){logger.error("error",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);}}}}

并在加载主词典及扩展词典方法 loadMainDict 中调用
在这里插入图片描述
增加从mysql加载停用词方法 loadMySQLStopwordDict

/*** 从mysql加载停用词*/private void loadMySQLStopwordDict() {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {Path file = PathUtils.get(getDictRoot(), "jdbc-reload.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());}Thread.sleep(Integer.valueOf(String.valueOf(prop.get("jdbc.reload.interval"))));} 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);}}}}

并在加载用户扩展的停止词词典方法 loadStopWordDict 中调用
在这里插入图片描述

3、打包

mvn package打包代码
把文件target\releases\elasticsearch-analysis-ik-7.8.0.zip放到es的plugins中

4、解压缩

将zip包解压,并把mysql驱动放到ik目录下

5、重启es

之后通过数据库添加分词或者停用词即可。

相关文章:

ES IK分词字典热更新

前言 在使用IK分词器的时候&#xff0c;发现官方默认的分词不满足我们的需求&#xff0c;那么有没有方法可以自定义字典呢&#xff1f; 官方提供了三种方式 一、ik本地文件读取方式 k插件本来已为用户提供自定义词典扩展功能&#xff0c;只要修改配给文件即可&#xff1a; …...

Mac连接云服务器工具推荐

文章目录 前言步骤1. 下载2. 安装3. 常用插件安装4. 连接ssh测试5. 连接sftp测试注意&#xff1a;ssh和sftp的区别注意&#xff1a;不同文件传输的区别解决SSL自动退出 前言 Royal TSX是什么&#xff1a; Royal TSX 是一款跨平台的远程桌面和连接管理工具&#xff0c;专为 mac…...

从零开始:如何在 .NET Core 中优雅地读取和管理配置文件

在.net中的配置文件系统支持丰富的配置源&#xff0c;包括文件(json、xml、ini等)、注册表、环境变量、命令行、Azure Key Vault等&#xff0c;还可以配置自定义配置源并跟踪配置的改变&#xff0c;然后按照优先级进行覆盖&#xff0c;总之对文件的配置有很多方法&#xff0c;这…...

JVM学习:CMS和G1收集器浅析

总框架 一、Java自动内存管理基础 1、运行时数据区 运行时数据区可分为线程隔离和线程共享两个维度&#xff0c;垃圾回收主要是针对堆内存进行回收 &#xff08;1&#xff09;线程隔离 程序计数器 虚拟机多线程是通过线程轮流切换、分配处理器执行时间来实现的。为了线程切换…...

Science Robotics让软机器人“活”得更久的3D打印!

软机器人硬件在医疗、探索无结构环境等领域有广泛应用&#xff0c;但其生命周期有限&#xff0c;导致资源浪费和可持续性差。软机器人结合软硬组件&#xff0c;复杂组装和拆卸流程使其难以维修和升级。因此&#xff0c;如何延长软机器人的生命周期并提高其可持续性成为亟待解决…...

模电面试——设计题及综合分析题0x01(含答案)

1、已知某温控系统的部分电路如下图&#xff08;EDP070252&#xff09;&#xff0c;晶体管VT导通时&#xff0c;继电器J吸合&#xff0c;压缩机M运转制冷&#xff0c;VT截止时&#xff0c;J释放&#xff0c;M停止运转。 &#xff08;1&#xff09;电源刚接通时&#xff0c;晶体…...

二层交换机和三层交换机

一、交换机简述 交换机的主要功能包括物理编址、网络拓扑结构、错误校验、帧序列以及流控。交换机还具备了一些新的功能&#xff0c;如对VLAN&#xff08;虚拟局域网&#xff09;的支持、对链路汇聚的支持&#xff0c;甚至有的还具有防火墙的功能。 交换机除了能够连接同种类型…...

每天五分钟机器学习:凸集

本文重点 在SVM中,目标函数是一个凸函数,约束集合是一个凸集。因此,SVM问题可以转化为一个凸规划问题来求解。这使得SVM在实际应用中具有较高的计算效率和准确性。 凸集的定义 凸集是指一个集合中的任意两点之间的线段都完全包含在这个集合中。换句话说,给定集合C中的两…...

Mongodb日志报错too many open files,导致mongod进程down

【解决方案】 &#xff08;1&#xff09;进入到服务器&#xff0c;执行&#xff1a; ulimit -a 查看&#xff1a;open files这一行的数量&#xff0c;如果查询到的结果是1000左右&#xff0c;那多半是服务器限制。 &#xff08;2&#xff09;在当前session窗口执行如下&…...

关于 PCB线路板细节锣槽问题 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144783817 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

硬件基础知识笔记(2)——二级管、三极管、MOS管

Part 2 二级管、三极管、MOS管 1、二级管1.1肖特基二极管和硅二极管选型比较1.2到底是什么决定了二极管的最高工作频率&#xff1f;1.3二极管结电容和反向恢复时间都是怎么来的 1、二级管 1.1肖特基二极管和硅二极管选型比较 肖特基二极管的优势主要在速度和压降&#xff0c;对…...

软件测试之非功能测试设计

非功能测试设计 非功能:除了软件功能测试&#xff0c;其他都是非功能测试。 1.兼容 2.易用 3.性能(专项) 4.安全(专项) Web浏览器 兼容:Chrome浏览器、Edge浏览器、Firefox浏览器、Safari苹果浏览器 易用:参考竞品&#xff0c;主观感受为主 总结 1.非功能测试范围 兼容性、…...

GPU 英伟达GPU架构回顾

1999 年&#xff0c;英伟达发明了 GPU&#xff08;graphics processing unit&#xff09;&#xff0c;本节将介绍英伟达 GPU 从 Fermi 到 Blackwell 共 9 代架构&#xff0c;时间跨度从 2010 年至 2024 年&#xff0c;具体包括费米&#xff08;Feimi&#xff09;、开普勒&#…...

机器学习 - 线性回归

线性回归模型的定义 线性回归&#xff08;Linear Regression&#xff09;的目标旨在找到可以描述目标值&#xff08;输出变量&#xff09;与一个或多个特征&#xff08;输入变量&#xff09;之间关系的一个线性方程或函数。 线性回归模型的表达式为 线性回归模型表达式的“齐次…...

NestJS 性能优化:从应用到部署的最佳实践

在上一篇文章中&#xff0c;我们介绍了 NestJS 的微服务架构实现。本文将深入探讨 NestJS 应用的性能优化策略&#xff0c;从应用层到部署层面提供全方位的优化指南。 应用层优化 1. 路由优化 // src/modules/users/users.controller.ts import { Controller, Get, UseInter…...

本地快速推断的语言模型比较:Apple MLX、Llama.cpp与Hugging Face Candle Rust

本地快速推断的语言模型比较&#xff1a;Apple MLX、Llama.cpp与Hugging Face Candle Rust 在自然语言处理&#xff08;NLP&#xff09;部署中&#xff0c;推断速度是一个关键因素&#xff0c;尤其是对于支持大型语言模型&#xff08;LLM&#xff09;的应用来说。随着Apple M1…...

您的公司需要小型语言模型

当专用模型超越通用模型时 “越大越好”——这个原则在人工智能领域根深蒂固。每个月都有更大的模型诞生&#xff0c;参数越来越多。各家公司甚至为此建设价值100亿美元的AI数据中心。但这是唯一的方向吗&#xff1f; 在NeurIPS 2024大会上&#xff0c;OpenAI联合创始人伊利亚…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之14 方案再探 之5:知识树三类节点对应的三种网络形式及其网络主机

本文要点 前面讨论过&#xff08;前面有错这里做了修正&#xff09;&#xff0c;三种簿册归档 对应通过不同的网络形式&#xff08;分布式、对等式和去中心式&#xff09;。每种网络主机上分别提供&#xff1a; 分布式控制脚本、 对等式账本 和 备记手本 通过以上讨论&#x…...

JR-RLAA系20路模拟音频多功能编码器

JR-RLAA系20路模拟音频多功能编码器 产品特色 (1)工业级19英寸标准设备&#xff0c;内置双电源 (2)内嵌Web Server&#xff0c;支持远程Web页面登陆后的统一配置操作 (3)支持20路音频输入 (4)支持Dolby Digital(AC-3) &#xff0c;MPEG-2&#xff0c;AAC-LC/HE-AAC&#x…...

LabVIEW冷却风机性能测试系统

开发了基于LabVIEW软件及LabSQL工具包的冷却风机性能测试系统。系统通过高效的数据库访问技术&#xff0c;实现了对冷却风机测试过程中关键性能数据的采集、存储与管理&#xff0c;优化了测试流程并提升了数据处理的效率。 ​ 项目背景 在工业生产和科研测试中&#xff0c;准…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...