网站怎么做动态背景图片,网站建设推广的方法,腾讯企业邮箱注册申请免费,一起做网站广州前言
在使用IK分词器的时候#xff0c;发现官方默认的分词不满足我们的需求#xff0c;那么有没有方法可以自定义字典呢#xff1f;
官方提供了三种方式
一、ik本地文件读取方式
k插件本来已为用户提供自定义词典扩展功能#xff0c;只要修改配给文件即可#xff1a; …前言
在使用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;}ListString 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; charsetutf-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.urljdbc:mysql://127.0.0.1:3307/test?serverTimezoneGMT
jdbc.userroot
jdbc.passwordabc123456
jdbc.reload.sqlselect word from hot_words
jdbc.reload.stopword.sqlselect stopword as word from hot_stopwords
jdbc.reload.interval1000添加热更新线程类 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
之后通过数据库添加分词或者停用词即可。