架构不变,为了学习方便,直接研究ElasticSearch-rtf版本。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
关于redis---配置文件中指定
redis:
pool:
maxactive: 20
maxidle: 10
maxwait: 100
testonborrow: true
ip: 127.0.0.1:6379
先修改为目的IP:
redis:
pool:
maxactive: 20
maxidle: 10
maxwait: 100
testonborrow: true
ip: 192.168.56.200:6379
启动redis和ElasticSearch-rtf版本。
~~~~~~~~~~~~~~~~~~~~~~~开始研究 redis篇
Q1:ElasticSeach什么时候连接上redis的?
A:
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服务器。
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:测试
添加停词前:
开始添加停词
查看效果:
再看持久化。
研究到此为止!
来源:oschina
链接:https://my.oschina.net/u/1382024/blog/278495