自定义字典控制器
首先新建一个控制器用来处理Rest请求的添加删除词典,以及查询词典。
package com.topcom.test.es.controller;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Author BigKang
* @Date 2021/1/28 1:58 下午
* @Motto 仰天大笑撸码去, 我辈岂是蓬蒿人
* @Summarize 字典控制器
*/
@RestController
public class DictController {
/**
* 最后修改时间
*/
private Date lastModified = new Date();
/**
* 停用词最后修改时间
*/
private Date stopLastModified = new Date();
/**
* 分词词典表
*/
private List<String> dictTable = new ArrayList<>();
/**
* 停用词词典表
*/
private List<String> stopDictTable = new ArrayList<>();
/**
* 初始化自定字典,也可以从数据库读取然后进行加载
*/
@PostConstruct
public void init() {
dictTable.add("aaa");
//dictTable.add("盖伦大宝剑");
stopDictTable.add("枪支");
stopDictTable.add("仿真枪");
}
/**
* 添加词典
* @param dict 词典
* @param stop 是否停用词
* @return
*/
@PostMapping("addDict")
public boolean addDict(String dict,Boolean stop) {
// 判断是否存在,如果不存在则添加
if (dict != null && dict.trim().length() > 0) {
// 如果不是停用词则添加到词典
if(stop == null || !stop && !dictTable.contains(dict)){
dictTable.add(dict);
lastModified = new Date();
return true;
}else if(stop && !stopDictTable.contains(dict)){
stopDictTable.add(dict);
stopLastModified = new Date();
return true;
}
}
return false;
}
/**
* 删除词典
* @param dict 词典
* @param stop 是否停用词
* @return
*/
@DeleteMapping("delDict")
public boolean delDict(String dict,Boolean stop) {
// 判断是否存在,如果不存在则添加
if (dict != null && dict.trim().length() > 0) {
// 如果不是停用词则添加到词典
if(stop == null || !stop && dictTable.contains(dict)){
dictTable.remove(dict);
lastModified = new Date();
return true;
}else if(stop && stopDictTable.contains(dict)){
stopDictTable.remove(dict);
stopLastModified = new Date();
return true;
}
}
return false;
}
/**
* 获取字典
* @param httpServletResponse
*/
@GetMapping("getCustomDict")
public void getCustomDict(HttpServletResponse httpServletResponse) throws IOException {
getDict(null,httpServletResponse);
httpServletResponse.flushBuffer();
}
/**
* 获取停用字典
* @param httpServletResponse
*/
@GetMapping("getCustomStopDict")
public void getCustomStopDict(HttpServletResponse httpServletResponse) throws IOException {
getDict(true,httpServletResponse);
httpServletResponse.flushBuffer();
}
/**
* 获取字典
* @param stop
* @param httpServletResponse
*/
public void getDict(Boolean stop,HttpServletResponse httpServletResponse) {
Long time = null;
String eTag = null;
List<String> dictTable = null;
if(stop == null || !stop){
time = lastModified.getTime();
dictTable = this.dictTable;
eTag = String.valueOf(this.dictTable.hashCode()) + "-" +String.valueOf(this.dictTable.size());
}else {
time = stopLastModified.getTime();
dictTable = this.stopDictTable;
eTag = String.valueOf(this.stopDictTable.hashCode()) + "-" +String.valueOf(this.stopDictTable.size());
}
httpServletResponse.setDateHeader("Last-Modified",time);
httpServletResponse.setHeader("ETag", eTag);
httpServletResponse.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
try (OutputStream outputStream = httpServletResponse.getOutputStream();){
StringBuilder str = new StringBuilder();
for (String dict : dictTable) {
str.append(dict);
str.append("\n");
}
outputStream.write(str.toString().getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
相应的接口地址以及描述
(分词词典)
添加词典:“APP地址”/addDict?dict=核心&stop=true
删除词典:“APP地址”/delDict?dict=禁止&stop=false
获取词典:“APP地址”/getCustomDict
获取停用词典:“APP地址”/getCustomStopDict
dict # 参数表示词典的词
stop # 表示是否停用词,停用词为True,空表示核心词典
然后我们进入IK的配置修改配置文件,新增两个远程词典
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
.......
<!-- 添加如下 -->
<!-- 远程扩展字典地址 -->
<entry key="remote_ext_dict">http://124.71.9.101:8080/getCustomDict</entry>
<!-- 远程停用字典地址 -->
<entry key="remote_ext_stopwords">http://124.71.9.101:8080/getCustomStopDict</entry>
</properties>
重启Es查看日志
[2021-01-28T09:48:40,407][INFO ][o.w.a.d.Monitor ] [elasticsearch] try load config from /usr/share/elasticsearch/config/analysis-ik/IKAnalyzer.cfg.xml
[2021-01-28T09:48:40,522][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] /usr/share/elasticsearch/config/analysis-ik/custom/mydict.dic
[2021-01-28T09:48:40,523][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] http://124.71.9.101:8080/getCustomDict
[2021-01-28T09:48:40,531][INFO ][o.w.a.d.Monitor ] [elasticsearch] aaa
[2021-01-28T09:48:40,532][INFO ][o.w.a.d.Monitor ] [elasticsearch] 黄康
[2021-01-28T09:48:40,532][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] http://124.71.9.101:8080/getCustomStopDict
[2021-01-28T09:48:40,541][INFO ][o.w.a.d.Monitor ] [elasticsearch] 枪支
[2021-01-28T09:48:40,542][INFO ][o.w.a.d.Monitor ] [elasticsearch] 仿真枪
[2021-01-28T09:48:40,542][INFO ][o.w.a.d.Monitor ] [elasticsearch] 重新加载词典完毕...
我们新增一个停用词测试即可发现Es会刷新词典,1分钟左右间隔扫描一次没有修改则不会刷新词典
[2021-01-28T09:59:40,238][INFO ][o.w.a.d.Monitor ] [elasticsearch] 重新加载词典...
[2021-01-28T09:59:40,238][INFO ][o.w.a.d.Monitor ] [elasticsearch] try load config from /usr/share/elasticsearch/config/analysis-ik/IKAnalyzer.cfg.xml
[2021-01-28T09:59:40,341][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] /usr/share/elasticsearch/config/analysis-ik/custom/mydict.dic
[2021-01-28T09:59:40,342][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] http://124.71.9.101:8080/getCustomDict
[2021-01-28T09:59:40,353][INFO ][o.w.a.d.Monitor ] [elasticsearch] aaa
[2021-01-28T09:59:40,353][INFO ][o.w.a.d.Monitor ] [elasticsearch] 黄康
[2021-01-28T09:59:40,353][INFO ][o.w.a.d.Monitor ] [elasticsearch] 盖伦大宝剑
[2021-01-28T09:59:40,354][INFO ][o.w.a.d.Monitor ] [elasticsearch] [Dict Loading] http://124.71.9.101:8080/getCustomStopDict
[2021-01-28T09:59:40,363][INFO ][o.w.a.d.Monitor ] [elasticsearch] 枪支
[2021-01-28T09:59:40,363][INFO ][o.w.a.d.Monitor ] [elasticsearch] 仿真枪
[2021-01-28T09:59:40,363][INFO ][o.w.a.d.Monitor ] [elasticsearch] 重新加载词典完毕...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。