当前位置: 首页 > 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;准…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...