liwh 1 місяць тому
батько
коміт
72fea86473

+ 6 - 0
config/jdbc-reload.properties

@@ -0,0 +1,6 @@
+jdbc.url=jdbc:mysql://10.168.1.47:18080/smart-search?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
+jdbc.user=root
+jdbc.password=Taiji@2023#data
+jdbc.reload.synonym.sql=select sw_name from sys_synonym_word where UNIX_TIMESTAMP(update_time) >=@lastModifiedFrom and UNIX_TIMESTAMP(update_time)<=@lastModifiedTo
+jdbc.lastModified.synonym.sql=select max(UNIX_TIMESTAMP(update_time)) as version from sys_synonym_word where 1=1
+jdbc.driver=com.mysql.cj.jdbc.Driver

+ 3 - 0
config/socketPolicy.policy

@@ -0,0 +1,3 @@
+grant {
+   permission java.net.SocketPermission "10.168.1.47:18080","connect,resolve";
+};

+ 5 - 0
pom.xml

@@ -100,6 +100,11 @@
             <version>${project.version}.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.21</version>
+        </dependency>
     </dependencies>
 
 

+ 14 - 0
src/main/assemblies/plugin.xml

@@ -30,5 +30,19 @@
                 <include>org.apache.httpcomponents:httpclient</include>
             </includes>
         </dependencySet>
+        <dependencySet>
+            <outputDirectory/>
+            <useProjectArtifact>true</useProjectArtifact>
+            <useTransitiveFiltering>true</useTransitiveFiltering>
+            <includes>
+                <include>mysql:mysql-connector-java</include>
+            </includes>
+        </dependencySet>
     </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.basedir}/config</directory>
+            <outputDirectory>config</outputDirectory>
+        </fileSet>
+    </fileSets>
 </assembly>

+ 244 - 0
src/main/java/com/bellszhu/elasticsearch/plugin/synonym/analysis/DBRemoteSynonymFile.java

@@ -0,0 +1,244 @@
+package com.bellszhu.elasticsearch.plugin.synonym.analysis;
+
+import com.bellszhu.elasticsearch.plugin.DynamicSynonymPlugin;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.synonym.SynonymMap;
+import org.elasticsearch.core.PathUtils;
+import org.elasticsearch.env.Environment;
+
+import java.io.*;
+import java.nio.file.Path;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Properties;
+
+/**
+ * mysql远程加载同义词
+ */
+public class DBRemoteSynonymFile implements SynonymFile {
+
+    // 配置文件名
+    private final static String DB_PROPERTIES = "jdbc-reload.properties";
+    private static Logger logger = LogManager.getLogger("dynamic-synonym");
+    private String format;
+
+    private boolean expand;
+
+    private boolean lenient;
+
+    private Analyzer analyzer;
+
+    private Environment env;
+
+    // 数据库配置
+    private String location;
+
+    private long lastModifiedFrom = 0L;
+
+    private long lastModifiedTo = 0L;
+
+    private Connection connection = null;
+
+    private Statement statement = null;
+
+    private Properties props;
+
+    private Path conf_dir;
+
+
+    DBRemoteSynonymFile(Environment env, Analyzer analyzer,
+                        boolean expand,boolean lenient, String format, String location) {
+        this.analyzer = analyzer;
+        this.expand = expand;
+        this.lenient = lenient;
+        this.format = format;
+        this.env = env;
+        this.location = location;
+        this.props = new Properties();
+
+        //读取当前 jar 包存放的路径
+        Path filePath = PathUtils.get(new File(DynamicSynonymPlugin.class.getProtectionDomain().getCodeSource()
+                        .getLocation().getPath())
+                        .getParent(), "config")
+                .toAbsolutePath();
+        this.conf_dir = filePath.resolve(DB_PROPERTIES);
+
+        //判断文件是否存在
+        File configFile = conf_dir.toFile();
+        InputStream input = null;
+        try {
+            input = new FileInputStream(configFile);
+        } catch (FileNotFoundException e) {
+
+            logger.info("jdbc-reload.properties not find. " + e);
+        }
+        if (input != null) {
+
+            try {
+                props.load(input);
+
+            } catch (Exception e) {
+                logger.error("fail to load the jdbc-reload.properties," + e);
+            }
+        }
+        isNeedReloadSynonymMap();
+    }
+
+    @Override
+    public SynonymMap reloadSynonymMap() {
+
+        try {
+            logger.info("start reload local synonym from {}.", location);
+
+            Reader rulesReader = getReader();
+
+            SynonymMap.Builder parser = RemoteSynonymFile.getSynonymParser(rulesReader, format, expand, lenient, analyzer);
+            return parser.build();
+
+        }catch (Exception e) {
+            logger.error("reload local synonym {} error!", e, location);
+            throw new IllegalArgumentException(
+                    "could not reload local synonyms file to build synonyms", e);
+        }
+    }
+
+    /**
+     * 判断是否需要进行重新加载
+     * @return true or false
+     */
+    @Override
+    public boolean isNeedReloadSynonymMap() {
+        try {
+            Long lastModify = getLastModify();
+            if (lastModifiedTo < lastModify) {
+                lastModifiedFrom= lastModifiedTo;
+                lastModifiedTo = lastModify;
+                return true;
+            }
+        } catch (Exception e) {
+            logger.error(e);
+        }
+
+        return false;
+    }
+
+    /**
+     * 同义词库的加载
+     * @return Reader
+     */
+    @Override
+    public Reader getReader() {
+
+        StringBuffer sb = new StringBuffer();
+        try {
+            ArrayList<String> dbData = getDBData();
+            for (int i = 0; i < dbData.size(); i++) {
+                logger.info("load the synonym from db," + dbData.get(i));
+                sb.append(dbData.get(i))
+                        .append(System.getProperty("line.separator"));
+            }
+
+        }catch (Exception e) {
+            e.printStackTrace();
+            logger.error("reload synonym from db failed");
+        }
+
+        return new StringReader(sb.toString());
+    }
+
+    /**
+     * 获取同义词库最后一次修改的时间
+     * 用于判断同义词是否需要进行重新加载
+     *
+     * @return getLastModify
+     */
+    public Long getLastModify() {
+
+        ResultSet resultSet = null;
+        Long last_modify_long = 0L;
+
+        try {
+
+            if (connection == null || statement == null) {
+                Class.forName(props.getProperty("jdbc.driver"));
+                connection = DriverManager.getConnection(
+                        props.getProperty("jdbc.url"),
+                        props.getProperty("jdbc.user"),
+                        props.getProperty("jdbc.password")
+                );
+                statement = connection.createStatement();
+            }
+            resultSet = statement.executeQuery(props.getProperty("jdbc.lastModified.synonym.sql"));
+            while (resultSet.next()) {
+                last_modify_long = resultSet.getLong("version");
+            }
+        } catch (ClassNotFoundException | SQLException e) {
+            logger.error("获取同义词库最后一次修改的时间",e);
+        } finally {
+
+            try {
+                if (resultSet != null) {
+
+                    resultSet.close();
+                }
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+
+        }
+        return last_modify_long;
+    }
+
+    /**
+     * 查询数据库中的同义词
+     * @return DBData
+     */
+    public ArrayList<String> getDBData() {
+
+        ArrayList<String> arrayList = new ArrayList<>();
+
+        ResultSet resultSet = null;
+        try {
+            if (connection == null || statement == null) {
+                Class.forName(props.getProperty("jdbc.driver"));
+                connection = DriverManager.getConnection(
+                        props.getProperty("jdbc.url"),
+                        props.getProperty("jdbc.user"),
+                        props.getProperty("jdbc.password")
+                );
+                statement = connection.createStatement();
+            }
+
+            String sql = props.getProperty("jdbc.reload.synonym.sql").replaceAll("@lastModifiedFrom",String.valueOf(lastModifiedFrom)).replaceAll("@lastModifiedTo",String.valueOf(lastModifiedTo));
+
+
+            resultSet = statement.executeQuery(sql);
+            while (resultSet.next()) {
+                String theWord = resultSet.getString("word");
+                arrayList.add(theWord);
+            }
+        }catch (ClassNotFoundException | SQLException e) {
+
+            e.printStackTrace();
+
+            logger.error("获取同义词库失败",e);
+
+        }finally {
+
+            try {
+                if (resultSet != null) {
+                    resultSet.close();
+                }
+
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+        return arrayList;
+    }
+
+}

+ 6 - 1
src/main/java/com/bellszhu/elasticsearch/plugin/synonym/analysis/DynamicSynonymTokenFilterFactory.java

@@ -159,7 +159,12 @@ public class DynamicSynonymTokenFilterFactory extends
     SynonymFile getSynonymFile(Analyzer analyzer) {
         try {
             SynonymFile synonymFile;
-            if (location.startsWith("http://") || location.startsWith("https://")) {
+
+            if (location.equals("fromDB")){
+
+                synonymFile = new DBRemoteSynonymFile(environment, analyzer, expand, lenient, format,location);
+
+            }else if (location.startsWith("http://") || location.startsWith("https://")) {
                 synonymFile = new RemoteSynonymFile(
                         environment, analyzer, expand, lenient,  format, location);
             } else {

+ 1 - 0
src/main/resources/plugin-security.policy

@@ -1,3 +1,4 @@
 grant {
   permission java.net.SocketPermission "*", "connect,resolve";
+  permission java.lang.RuntimePermission "setContextClassLoader";
 };