前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES -IK分词器分词、停用词基于API实现热更新

ES -IK分词器分词、停用词基于API实现热更新

作者头像
IT小马哥
发布2023-02-13 13:44:36
9650
发布2023-02-13 13:44:36
举报
文章被收录于专栏:Java TaleJava Tale

官方介绍

ik的github有关于热更新的介绍

字典配置

代码语言:javascript
复制
IKAnalyzer.cfg.xml` can be located at `{conf}/analysis-ik/config/IKAnalyzer.cfg.xml` or `{plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords">custom/ext_stopword.dic</entry>
 	<!--用户可以在这里配置远程扩展字典 -->
	<entry key="remote_ext_dict">location</entry>
 	<!--用户可以在这里配置远程扩展停止词字典-->
	<entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry>
</properties>

热更新 IK 分词使用方法

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

代码语言:javascript
复制
 	<!--用户可以在这里配置远程扩展字典 -->
	<entry key="remote_ext_dict">location</entry>
 	<!--用户可以在这里配置远程扩展停止词字典-->
	<entry key="remote_ext_stopwords">location</entry>

其中 location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。

  1. 该 http 请求需要返回两个头部(header),一个是 Last-Modified,一个是 ETag,这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
  2. 该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

说明

Last-Modified是上次更新时间 ETag是实体标签(Entity Tag)的缩写,根据实体内容(文本数据)生成的一段hash字符串,可以通过它的标识数据的修改状态,当数据发生改变时,ETag也随之改变

思路

分词文件可以存放在一个文本文件中,注意文件需要时UTF-8编码格式的。放在nginx或者其他简易http server下,当文件修改时,http server会在客户端请求该文件时自动返回相应的Last-Modified和ETag。

另外可以做一个工具来从业务系统提取相关词汇,再更新到这个文件中

如何设置ETag的值

首先ETag要满足以下三个条件: 1、当文件内容改变时,ETag值跟着改变 2、计算简单,不会特别消耗CPU(因此就不能使用MD5、SHA128、SHA256等算法) 3、必须支持横向扩展,也就是在不同的服务器节点上生成的ETag是一样的

参考Nginx中ETag的生成: 由Last-Modified和content_length表示为16进制组合而成

代码语言:javascript
复制
etag = '"' + Long.toHexString(lastModified) + '-' + Long.toHexString(contentLength) + '"';

有了Last-Modified为什么还需要ETag

1、原因就是因为某些服务器如果不能精确的获取到数据的最后修改时间的话,那么就无法通过Last-Modified来判断数据是否有更新了,就会导致词库更新不及时,出现延迟的问题。

2、Last-Modified一般只能精确到秒,如果数据更新的比较频繁的话,会导致识别不到更新,当然这点在IK分词器中不存在,因为IK分词器的热更新默认是一分钟获取一次。

3、如果我在一分钟内改了文件,发现改错了,又改回来了,那么这个时间虽然修改时间变了,但是因为内容没变,我是不希望更新它的。

综上所述,我们需要一个ETag来帮助我们判断是否更新了文本内容,同时ETag还需要根据文本内容来产生。

代码

代码语言:javascript
复制
@RequestMapping("updateHotWord")
    public void hotWord1(HttpServletResponse response, @RequestParam Integer type) throws IOException {
        List<String> dict = new ArrayList();
        if(type == 1){
            //TODO 直接读取数据库维护 热词
        }else{
            //TODO 直接读取数据库维护 停止词
        }
        String str = dict.parallelStream().collect(Collectors.joining("\n"));
        Long lastModified = Instant.now().toEpochMilli();
        String etag =   Long.toHexString(str.length());
        response.setHeader("Last-Modified",String.valueOf(lastModified));
        response.setHeader("ETag",etag);
        response.setContentType("text/plain;charset=utf-8");
        OutputStream out = response.getOutputStream();
        out.write(str.getBytes());
        out.flush();
    }

配置

修改ik分词器配置文件IKAnalyzer.cfg.xml

代码语言:javascript
复制
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">custom/my_extend.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <entry key="remote_ext_dict">http://localhost:8080/hot/updateHotWord?type=0</entry>
        <!--用户可以在这里配置远程扩展停止词字典-->
         <entry key="remote_ext_stopwords">http://localhost:8080/hot/updateHotWord?type=1</entry>
</properties> 

重启es 会发现启动时会显示读取的分词内容

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 官方介绍
    • 字典配置
      • 热更新 IK 分词使用方法
        • 说明
        • 思路
          • 如何设置ETag的值
            • 有了Last-Modified为什么还需要ETag
            • 代码
            • 配置
            相关产品与服务
            Elasticsearch Service
            腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档