环境
系统:CentOS
Elasticsearch:7.6.2
IK:7.6.2
DB:Oracle
步骤
- 下载指定版本IK的source code ,地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
- 在config目录下增加jdbc-reload.properties
jdbc.url=jdbc:oracle:thin:@10.10.200.42:1521:orcl
jdbc.user=credit_law
jdbc.password=credit_law
jdbc.reload.sql=SELECT EXT_WORD FROM ES_IK_EXT_WORD T WHERE T.VERSION > (SELECT nvl(MAX(WORD_VER),0) FROM \
ES_IK_EXT_WORD_VER)
jdbc.reload.stop_word.sql=SELECT STOP_WORD FROM ES_IK_STOP_WORD T WHERE T.VERSION > (SELECT nvl(MAX(STOP_WORD_VER),0)\
FROM ES_IK_EXT_WORD_VER)
jdbc.reload.update_version.sql = INSERT INTO ES_IK_EXT_WORD_VER(WORD_VER, STOP_WORD_VER)VALUES ((SELECT nvl(MAX(VERSION), 0) FROM ES_IK_EXT_WORD), (SELECT nvl(MAX(VERSION), 0) FROM ES_IK_STOP_WORD))
jdbc.reload.ext_word=EXT_WORD
jdbc.reload.stop_word=STOP_WORD
period_time_seconds=60
- 在Dictionary中添加数据库驱动
static {
try {
//驱动默认选择oracle
logger.info("初始化驱动开始..............");
Class.forName("oracle.jdbc.OracleDriver");
logger.info("初始化驱动完成..............");
} catch (Exception e) {
logger.error("初始化驱动失败..............",e);
}
}
- 在Dictionary类中添加全局变量
private Properties props;
- 在Dictionary构造方法最后添加读取db的配置的方法
try {
Path file = PathUtils.get(getDictRoot(), "jdbc-reload.properties");
dbProps = new Properties();
dbProps.load(new FileInputStream(file.toFile()));
logger.info("dbProps:{}",dbProps);
} catch (IOException e) {
logger.error("db配置文件读取失败", e);
}
- 在Dictionary类中添加创建数据库链接的方法
private Connection getConn() {
Connection conn = null;
try {
logger.info("创建数据连接");
// 创建数据连接
conn = DriverManager.getConnection(
dbProps.getProperty("jdbc.url"),
dbProps.getProperty("jdbc.user"),
dbProps.getProperty("jdbc.password")
);
logger.info("创建数据连接成功..........");
} catch (Exception e) {
logger.error("创建数据连接失败..............",e);
}
return conn;
}
- 在Dictionary类中增加从数据获取词库的方法
public boolean loadOracleHotDict() throws Exception {
ResultSet rs = null;
boolean change = false;
try (Connection conn = getConn();Statement stmt =conn.createStatement() ){
logger.info("hot words loading");
String sql = dbProps.getProperty("jdbc.reload.sql");
logger.info("jdbc.reload.sql:{}",sql);
if(sql != null && !"".equals(sql)){
rs = stmt.executeQuery(sql);
while(rs.next()) {
change = true;
String theWord = rs.getString(dbProps.getProperty("jdbc.reload.ext_word"));
logger.info("hot word from oracle: " + theWord);
_MainDict.fillSegment(theWord.trim().toCharArray());
}
}
logger.info("hot words load end");
return change;
} catch (Exception e) {
logger.error("热词更新异常:",e);
throw new Exception("热词更新异常:",e);
} finally {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
logger.error("error", e);
}
}
}
}
public boolean loadMyOracleStopWordDict() throws Exception {
ResultSet rs = null;
boolean change = false;
try (Connection conn = getConn();Statement stmt =conn.createStatement()){
logger.info("stop words loading");
String sql = dbProps.getProperty("jdbc.reload.stop_word.sql");
logger.info("jdbc.reload.stop_word.sql:{}",sql);
if(sql != null && !"".equals(sql)){
rs = stmt.executeQuery(sql);
while(rs.next()) {
change = true;
String theWord = rs.getString(dbProps.getProperty("jdbc.reload.stop_word"));
logger.info("stop word from oracle: " + theWord);
_StopWords.fillSegment(theWord.trim().toCharArray());
}
}
logger.info("stop words load end");
return change;
} catch (Exception e) {
logger.error("停止词更新异常:",e);
throw new Exception("停止词更新异常:",e);
} finally {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
logger.error("error", e);
}
}
}
}
private void updateVersion() throws Exception{
try (Connection conn = getConn(); Statement stmt = conn.createStatement()){
logger.info("update word version");
String sql = dbProps.getProperty("jdbc.reload.update_version.sql");
logger.info("upload version sql:{}:",sql);
stmt.executeUpdate(sql);
conn.commit();
logger.info("update word version end");
}catch (Exception e){
logger.error("更新词库版本异常:",e);
throw new Exception("更新词库版本异常:",e);
}
}
- 在Dictionary类中增加调用上述方法的方法
public void reLoadSQLDict() throws Exception {
boolean extChange = this.loadOracleHotDict();
boolean stopChange = this.loadMyOracleStopWordDict();
if (extChange|| stopChange){
this.updateVersion();
}
}
- 在dic目录下创建OracleDictReloadTread类
public class OracleDictReloadThread implements Runnable {
private static final Logger logger = ESPluginLoggerFactory.getLogger(OracleDictReloadThread.class.getName());
@Override
public void run() {
logger.info("reloading hot_word and stop_word dict from oracle");
try {
Dictionary.getSingleton().reLoadSQLDict();
} catch (Exception e) {
logger.error("调用热词更新方法异常:",e);
}
}
}
- 在Dictionary类的initial方法中添加线程
public static synchronized void initial(Configuration cfg) {
if (singleton == null) {
synchronized (Dictionary.class) {
if (singleton == null) {
singleton = new Dictionary(cfg);
singleton.loadMainDict();
singleton.loadSurnameDict();
singleton.loadQuantifierDict();
singleton.loadSuffixDict();
singleton.loadPrepDict();
singleton.loadStopWordDict();
if(cfg.isEnableRemoteDict()){
// 建立监控线程
for (String location : singleton.getRemoteExtDictionarys()) {
// 10 秒是初始延迟可以修改的 60是间隔时间 单位秒
pool.scheduleAtFixedRate(new Monitor(location), 10, 60, TimeUnit.SECONDS);
}
for (String location : singleton.getRemoteExtStopWordDictionarys()) {
pool.scheduleAtFixedRate(new Monitor(location), 10, 60, TimeUnit.SECONDS);
}
}
logger.info("查数据库更新线程启动--------------------");
pool.scheduleAtFixedRate(new OracleDictReloadThread(), 10, Integer.parseInt(dbProps.getProperty("period_time_seconds")), TimeUnit.SECONDS);
}
}
}
}
- 在pom文件中添加依赖并更改es版本
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.1.0</version>
</dependency>
<elasticsearch.version>7.6.2</elasticsearch.version>
- 在src\main\assemblies\plugin.xml中添加配置使得数据库相关依赖一并打包
<dependencySet>
<outputDirectory/>
<useProjectArtifact>true</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>com.oracle:ojdbc6</include>
</includes>
</dependencySet>
- 打包,执行maven命令
mvn clean package -Dmaven.test.skip=true
- 将target/releases下的包上传至es服务器
- 修改permission
- 如果es启动用的是es的jdk,进入$/jdk/lib/security
- 修改default.policy
- 在最后的grant中添加
permission java.util.PropertyPermission "*","read,write";
permission java.net.SocketPermission "*","connect,resolve,accept,listen";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
-
保存并退出
-
关闭es,删除原es的ik
# 直接删除es根目录下的config和plugin目录下的ik目录即可
rm -rf ${ES_HOME}/config/ik ${ES_HOME}/plugins/ik
- 安装ik
无警告即为安装成功
elasticsearch-plugin install file://app/elasticsearch-analysis-ik-7.6.2.zip
- 重启es
elasticsearch -d
SQL
create table ES_IK_STOP_WORD
(
STOP_WORD VARCHAR(100 char) not null,
VERSION NUMBER(10) not null
)
/
comment on table ES_IK_STOP_WORD is 'ES IK分词器停用词'
/
comment on column ES_IK_STOP_WORD.STOP_WORD is '停用词'
/
comment on column ES_IK_STOP_WORD.VERSION is '版本号'
/
create index ES_IK_STOP_WORD_VERSION_INDEX
on ES_IK_STOP_WORD (VERSION desc)
/
create table ES_IK_EXT_WORD
(
EXT_WORD VARCHAR(100 char) not null,
VERSION NUMBER(10) not null
)
/
comment on table ES_IK_EXT_WORD is 'ES IK分词器扩展词'
/
comment on column ES_IK_EXT_WORD.EXT_WORD is '扩展词'
/
comment on column ES_IK_EXT_WORD.VERSION is '版本号'
/
create index ES_IK_EXT_WORD_VERSION_INDEX
on ES_IK_EXT_WORD (VERSION desc)
/
create table ES_IK_EXT_WORD_VER
(
WORD_VER NUMBER(10) not null,
STOP_WORD_VER NUMBER(10) not null
)
/
comment on table ES_IK_EXT_WORD_VER is '词库版本'
/
comment on column ES_IK_EXT_WORD_VER.WORD_VER is '扩展词版本'
/
comment on column ES_IK_EXT_WORD_VER.STOP_WORD_VER is '停用词版本'
/
create index ES_IK_EXT_WORD_VER_WORD_INDEX
on ES_IK_EXT_WORD_VER (WORD_VER desc)
/
create index ES_IK_EXT_WORD_VER_STOP_INDEX
on ES_IK_EXT_WORD_VER (STOP_WORD_VER desc)
/
create sequence SEQ_ES_IK_STOP_WORD
maxvalue 9999999999
order
/
create sequence SEQ_ES_IK_EXT_WORD
maxvalue 9999999999
order
/
insert into ES_IK_EXT_WORD_VER values (0,0)
/