赞
踩
需求目的:
es的ik分词器能够根据自定义的分词库对输入的关键词进行分词,但是不能够像jieba分词一样返回分词后的词性,一些需求可能除了需要分词外还需要知道词的词性来进行后续的业务处理,就需要自定义ik分词器返回的结果词的词性。
实现原理:
在es分词的返回结果中,有一个type字段,这个字段通常会用来返回该词的一些类别,如是否是中文分词,还是英文分词,或者是数量词。但是有些时候这些分词可能还不能够满足业务的需要,所以就需要对这这个type进行自定义返回。如在分词库中自定义了分词为“万福”,然后为其添加一个属性为地点“TYPE_PLACENAME”,那么在输入的文本中有带有万福的分词,type返回就会为自定义的TYPE_PLACENAME。
实现过程:
通过修改ik分词库源码的方式来实现,以及本次的实现基于读取的是远程mysql的分词库。ik实现远程读取mysql分词库的方式可参照我的上一篇文章
ik源码下载地址:https://github.com/medcl/elasticsearch-analysis-ik 根据自行的es版本 更改pom版本号为对应版本
ps:为了方便理解,图片可能较多
(1)打开源码,通过分词器上下文类AnalyzeContext可以知道,其中最终的分词结果集,存储在Lexeme。
找到Lexeme类,该类是ik分词返回结果tokens中的词元对象,其中有定义一些type包括中文分词,英文分词、数量词等。我们可以将我们需要自定义返回的type,定义在该类中
(2)定义好返回结果后,接下来找到待处理的分词队列类,hit,在其中设置一个自定义属性的字段,用来后续判断读取的分词库的分词是否为自定义分词
(3)定义好返回结果和待处理的分词队列中的属性后,就可以在对应的分词器处理器中编写我们自定义词性的代码,因为我这边主要是对中文分词进行处理,所以找到中文分词器处理类
在分词的处理方法中,对待处理队列里的分词进行判断,是为自定义的属性词,如果是话,则返回自定义的属性。这里我做了一个枚举
(4)上述步骤完成后,中文分词器已经会根据待处理的分词属性来返回自定义的属性结果了。接下来来处理词典类,我们从mysql数据库中读取的分词都会被存放在词典中。从分词器源码的如下方法中,我们可以知道,用户输入的待处理队列,通过与词典词进行匹配,来进行对文本进行分词的过程。
那我们要做的就是在词典树的分段类中,也添加一下自定义属性的字段
回到上面提到的,匹配词典分词的方法,继续往下找到DictSegment的match()匹配字段的方法
在匹配结果为完全匹配时,顺便将自定义字段的属性进行传递
(5)最后,修改加载词典的方法,将数据库中读取到的自定义属性放入到词典中就行了。
修改填充字典片段的方法,将自定义属性放入词典
以上。修改完源码后打包解压放入elasticsearch plugins文件夹下,重启es即可。属性值property默认为0,为0时返回原有的type,当不为0时返回自定义结果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。