我的架构演化笔记 10:ElasticSearch的分词器之ansj研究

拈花ヽ惹草 提交于 2019-12-02 07:49:33

架构不变,为了学习方便,直接研究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:测试

 添加停词前:

 开始添加停词

 

查看效果:

 

再看持久化。

 

研究到此为止!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!