#Dynamic Synonym for ElasticSearch
动态同义词插件,它可以重新加载同义词文件(本地文件或远程文件)
##Version
| dynamic synonym version | ES version |
| :----- | ----: |
| master | 7.x -> master |
| 6.1.4 | 6.1.4 |
| 5.2.0 | 5.2.0 |
##Statement说明
LocalSynonymFile类和RemoteSynonymFile类,其作用分别是读取本地文件获取同义词数据 和 请求远程同义词数据的
![img.png](img.png)
读取远程数据库资源,在项目的跟目录下有一个文件夹config,数据库配置文件jdbc-reload.properties,配置如下
jdbc.url=数据库url
jdbc.user=账号
jdbc.password=密码
# 查询同义词信息sql
jdbc.reload.synonym.sql=select keyword as words from synonym where is_delete = 0;
# 查询数据库同义词在数据库版本号sql
jdbc.reload.swith.synonym.version=SELECT version FROM synonym_version ORDER BY id DESC LIMIT 1;
DynamicSynonymTokenFilterFactory类的getSynonymFile(Analyzer analyzer)方法触发调用MySql数据库的查询
if ("fromMySql".equals(location)) {
synonymFile = new MySqlRemoteSynonymFile(environment, analyzer, expand, lenient, format, location);
}
pom文件中引入jdbc驱动的依赖包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
完成上述步骤后,开始进行源码编译,使用maven依次执行 clean、compile、package,然后在编译后的target/releases目录下找到编译后的插件安装包文件.zip;
将其拷贝到ES的安装目录下的\plugins\dynamic-synonym目录下并解压后删除压缩包;然后将jdbc驱动拷贝到当前目录下(若有jdbc驱动则无需拷贝)
![img_2.png](img_2.png)
##用法
在新建索引的时候
{
"index" : {
"analysis" : {
"analyzer" : {
"synonym" : {
"tokenizer" : "whitespace",
"filter" : ["remote_synonym"]
}
},
"filter" : {
"remote_synonym" : {
"type" : "dynamic_synonym",
"synonyms_path" : "fromMySql",
"interval": 60
},
"local_synonym" : {
"type" : "dynamic_synonym",
"synonyms_path" : "synonym.txt"
},
"synonym_graph" : {
"type" : "dynamic_synonym_graph",
"synonyms_path" : "http://host:port/synonym.txt"
}
}
}
}
}
同义词库和同义词库版本号各一张数据库表,当数据库中的词库版本号发生变更时,则会触发同步同义词操作,在实际生产环境的应用场景中ES通常是集群搭建,
所以采用版本号可以很好的适应集群环境;从而保证每个集群都可以同步生效。
###同义词库表
![img_1.png](img_1.png)
CREATE TABLE `synonym` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`keyword` varchar(500) DEFAULT NULL COMMENT '同义词',
`version` bigint(10) DEFAULT NULL COMMENT '版本号',
`is_delete` bit(1) DEFAULT b'0' COMMENT '是否删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
###同义词库版本号表
![img_3.png](img_3.png)
CREATE TABLE `synonym_version` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`version` bigint(20) DEFAULT NULL COMMENT '版本号',
`desc` varchar(500) DEFAULT NULL COMMENT '版本备注',
`date` date DEFAULT NULL COMMENT '版本创建日期',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
每60s系统会根据最新版本号来判断是否需要同步同义词库,若最新版本号为当前版本号则不更新,若高于当前版本号,则同步。
##***注意!注意!注意!重要的事情说三遍***
**ES的版本必须是7.16.3,此版本以下动态同义词热更新会不兼容**
##异常问题
###1.启动报错
java.lang.ExceptionInInitializerError
at java.base/java.lang.Class.forName0(Native Method)
解决方法
es安装目录 config 下新建 policy.policy文件,添加如下内容
grant {
permission java.net.SocketPermission "*:*","connect,resolve";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
};
修改jvm.option文件增加
-Djava.security.policy=你的es安装目录/config/policy.policy
重启es。