先 了解下es 如何添加 ik分词器插件,然后再说维护热词到数据库。
1 先去git 上 clone 你对应版本的ik分词器 https://github.com/medcl/elasticsearch-analysis-ik.git
2 先在pom中添加mysql的jar,还有连接池的包。我是用的druid.
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.18</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency>
3 找到 Dictionary 这个类,添加属性
private final static String WORD_SQL = "select * from worddic ORDER BY create_time limit 0,50"; static PreparedStatement preparedStatement = null;
第一个属性是我把我的关键词扩展放到数据库后,每次倒叙排序,取50个,来更新ik的词库
第二个属性是下面写mysql数据源使用的
添加数据源方法,在静态块中添加,这样在启动es的时候,会连接数据库
static{ try { DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mall?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"); druidDataSource.setUsername("root"); druidDataSource.setPassword("root"); // druidDataSource.setPassword("EqKUGJ1CnLkkmYvp5lfxFDoDnkQG0i54/dbPryEo78Da0TBNLft1pOuzYUJzGrDRB6tuEuhg3wO605aJUirqRA=="); // druidDataSource.setFilters("config"); druidDataSource.setDriverClassName("com.mysql.jdbc.Driver"); druidDataSource.setConnectionProperties("config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKvPPQFi4A9v4zzY5Nib1RvrXN1q+k/ksvH9qErrNk4GrZYjdbHoGTgnrkGmJgJPy9O5ec3qKZbTX64X+4QkfJcCAwEAAQ=="); druidDataSource.setDbType("com.alibaba.druid.pool.DruidDataSource"); druidDataSource.init(); preparedStatement = druidDataSource.getConnection().getConnection().prepareStatement(WORD_SQL); } catch (SQLException e) { logger.error("o my god 数据库初始化失败!!!!"); e.printStackTrace(); } }
4 添加一个加载关键词的方法
public void loadMysqlDict(){ try { // _MysqlWords = new DictSegment((char) 0); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()){ _MainDict.fillSegment(resultSet.getString(2).toCharArray()); } } catch (SQLException e) { logger.error("o my god 查询字典出错"); e.printStackTrace(); } }
5 在 reLoadMainDict 方法和 loadMainDict 方法中调用刚刚添加的 loadMysqlDict。
6 新建一个类实现runnable接口,构造方法传入Dictionary,然后在run方法中调用
Dictionary.getSingleton().reLoadMainDict();
public class HotDictReloadThread implements Runnable{ private Dictionary dictionary; public HotDictReloadThread(Dictionary dictionary) { this.dictionary = dictionary; } @Override public void run() { Dictionary.getSingleton().reLoadMainDict(); } }
7 在Dictionary找到164行或者 找到这句代码 if(cfg.isEnableRemoteDict()){。
在这个判断的后边启动你刚刚的线程类。
pool.scheduleAtFixedRate(new HotDictReloadThread(singleton),10,5,TimeUnit.SECONDS);
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); } pool.scheduleAtFixedRate(new HotDictReloadThread(singleton),10,5,TimeUnit.SECONDS); }
然后就完成了。这里我碰到一个小坑。 java.security.accesscontrolexception: access denied .解决方案是看网上找的,在
java/lib/security/java.policy(注意jdk和jre的都改)的grant 添加一行 permission java.security.allpermission;
到此打完收工!
看看效果,这个没有被分词