架构不变,为了学习方便,直接研究ElasticSearch-rtf版本。java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~redis
关于redis---配置文件中指定json
redis: pool: maxactive: 20 maxidle: 10 maxwait: 100 testonborrow: true ip: 127.0.0.1:6379
先修改成目的IP:ubuntu
redis: pool: maxactive: 20 maxidle: 10 maxwait: 100 testonborrow: true ip: 192.168.56.200:6379
启动redis和ElasticSearch-rtf版本。服务器
~~~~~~~~~~~~~~~~~~~~~~~开始研究 redis篇架构
Q1:ElasticSeach何时链接上redis的?app
A:curl
root@ubuntu:/usr/local/elasticsearch-rtf/elasticsearch-rtf# lsof -i:6379 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME redis-ser 1927 root 4u IPv6 11682 0t0 TCP *:6379 (LISTEN) redis-ser 1927 root 5u IPv4 11683 0t0 TCP *:6379 (LISTEN) root@ubuntu:/usr/local/elasticsearch-rtf/elasticsearch-rtf# lsof -i:6379 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME redis-ser 1927 root 4u IPv6 11682 0t0 TCP *:6379 (LISTEN) redis-ser 1927 root 5u IPv4 11683 0t0 TCP *:6379 (LISTEN) redis-ser 1927 root 6u IPv4 13373 0t0 TCP localhost:6379->localhost:47239 (ESTABLISHED) java 1970 root 190u IPv6 12427 0t0 TCP localhost:47239->localhost:6379 (ESTABLISHED)
可见,系统启动时,es根据配置项链接redis服务器。elasticsearch
Q2:ansj插件使用了redis的什么功能来支持动态修改词典的词?学习
A: redis提供了channel频道,使用publish命令来发布消息,subscribe来订阅这个频道,unsubscribe来取消订阅频道。
Q3:redis的channel频道自己是否持久化发布的消息?
A:根据测试代表,publish命令发布后,redis只会给当前链接的客户端发送消息,给全部链接的客户端发送完毕后,自己内存不存储消息,既然内存中不存储,天然也不会持久化到redis硬盘里。 固然咱们并不须要在redis端存储,而是在es端存储。
~~~~~~~~~~~~~~~~~~~~~~Ansj篇
Q4:经过redis对es添加动态的分词后,对es的分词会有什么影响?
A:下面咱们来测试,添加脚本指定了映射分词器query_ansj.
curl -i -XPUT 'http://localhost:9200/dew/_mapping/mobile' -d ' { "properties": { "title":{"type":"string","index":"analyzed","index_analyzer": "index_ansj","search_analyzer": "query_ansj"}, "content":{"type":"string","index":"analyzed","index_analyzer": "index_ansj","search_analyzer": "query_ansj"}, "tags":{"type":"string","index":"analyzed","index_analyzer": "index_ansj","search_analyzer": "query_ansj"} } } '
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Content-Length: 21 {"acknowledged":true}
代表建立映射方式成功。
添加分词前,测试截图以下,特地选择了一个真实的网上电视剧标题来作测试:【很是卧底第一季(Graceland) 第12集】
而后经过redis添加分词
再来查看分词效果:
可见是增长了一个“很是卧底”
再来一下测试:
查看分词效果:
不过这里看到“第一季”“第12集”是能够分别出来的。
Q5:动态添加的词是否可持久化?
A: 如图所示:
可见ansj插件作了持久化机制,这点很赞!
Q6:ansj的歧义纠正是什么?
A:普通的分词是根据词典来进行分词的,在这以前会参考歧义词典来进行纠正,因此若是歧义词典
有你想纠正歧义的语句,会优先根据歧义纠正语句来分词。例子以下:
【很可能形成其余的错误】
设定前:
经过redis添加:
查看如今的分词效果:
Q7:ansj的动态歧义分词是否可持久化?
A:支持,见图
Q8:ansj是否支持经过redis动态添加/删除stopWord?
A:从资料和代码来看,rtf版代码自己是不直接支持的,不过能够经过修改源码来实现这个效果。
Q9:如何修改源码来支持经过redis动态添加/删除stopWord?
A:
1)文件持久化支持
新增的方法-【FileUtils】类
public static void appendStopWord(String content) { try { File file = new File( AnsjElasticConfigurator.environment.configFile(), "ansj/stopLibrary.dic"); appendFile(content, file); } catch (IOException e) { logger.error("read exception", e, new Object[0]); e.printStackTrace(); } } public static void removeStopWord(String content) { try { File file = new File( AnsjElasticConfigurator.environment.configFile(), "ansj/stopLibrary.dic"); removeFile(content, file, false); } catch (FileNotFoundException e) { logger.error("file not found $ES_HOME/config/ansj/stopLibrary.dic"); new Object[0]); e.printStackTrace(); } catch (IOException e) { logger.error("read exception", e, new Object[0]); e.printStackTrace(); } }
编译成功,这样就支持了stopWord的持久化的增长/删除。
3)经过redis消息来触发内存/文件的更新编译,完成。
else if ("s".equals(msg[0])) { if ("c".equals(msg[1])) { // add one stopWord into memory AnsjElasticConfigurator.filter.add(msg[2]); // add one stopWord into file FileUtils.appendStopWord(msg[2]); } else if ("d".equals(msg[1])) { // remove one stopWord from memory AnsjElasticConfigurator.filter.remove(msg[2]); // remove one stopWod from file FileUtils.removeStopWord(msg[2]); } }
final:测试
添加停词前:
开始添加停词
查看效果:
再看持久化。
研究到此为止!