经常看到不少人问solr的IK分词如何配置,如何实现中文动态词库添加这类问题,中文分词看来还是solr使用的一个容易卡住的地方。其实solr自带中文分词smartcn,它是个ictclas智能分词的java版。如果想体验一下smartcn的效果是比较简单的,配上对应的tokenizerFactory就可以了,但smartcn不支持动态增加词库。
我们都知道一般词库都是单例,想动态修改词库要么保证词库具有线程安全的动态结构,要么就开放reload方法,先临时建好词库再把主词库切换到临时的。主流的分词器估计都不怎么支持这两点,但是第二点比较容易通过修改源码达到。前段时间把IK和ansj分词都增加了这个功能。
现在主流的java分词器里面这两个比较好,其他作者要么不怎么更新,要么特点被他们覆盖。IK分词器功能简单实用,还带了型号类型的切分能力;而ansj也是ictclas的改写版,切分准确而且性能极好。两个分词器各有特点,大家可以自行选择。下面简要介绍一下如何配置
先介绍一下IK的使用,源码到github上下载使用maven打包出jar包, 放入collection所需的lib中,在schema下添加字段类型:
<fieldType name="text_cn" class="solr.TextField" positionIncrementGap="100" > <analyzer type="index" > <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" /> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/> </analyzer> </fieldType>
1. useSmart表示是否启动智能切分模式,建议使用false。
2. conf表示在schema.xml所在目录下的一个文件,例子中是ik.conf,这个文件用来存放IKTokenizerFactory:
lastupdate=123 files=extDic.txt,aaa.txt其中lastupdate用数字,词库线程会定期检查conf文件这个值,如果比上一次大就会触发一次reload词库的动作;
files表示schema.xml路径下的一个或多个词库文件,以英文逗号分隔,要求:UTF-8编码,一行一个词但不以#开始。
由于词库是单例,因此在有IKTokenizerFactory 一个地方配置了conf就会启用自动reload检查。
ansj的使用和IK比较接近,先到github上下载源码,记得完成编译之后是三个jar,包放入collection所需的lib中,在schema下添加字段类型::
<fieldType name="text_cn" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="org.ansj.solr.AnsjTokenizerFactory" conf="ansj.conf"/> </analyzer> <analyzer type="query"> <tokenizer class="org.ansj.solr.AnsjTokenizerFactory" analysisType="1"/> </analyzer> </fieldType>
1. conf和上述IK的配置说明一样
2.analysisType="1" 表示分词类型,1代表标准切分,不写默认是0。是索引类型切分(也就是可能多分出一点词)
3. rmPunc="false" 表示不去除标点符号。默认不写是true,表示去掉标点符号。
我并没有使用分词器原始的添加词库方式,他们提供的主要都是从文件系统读取,solrcloud而用的是zookeeper配置,所以我改成了从ResourceLoader获取用户词源;另外为动态reload而增加的线程,根据solr界面的thread dump来观察,在collection被卸载后并没被JVM回收,因此如果需要反复添加卸载索引的,建议定期重启SOLR;如果想使用mmseg,paoding等老牌分词器可以参考我写的源码来修改。中文分词虽然可以动态改变,但索引的数据是没变的,因此可能会出现现在改了词库搜不出来,所以需要改变了词库以后进行一次重建操作。
除了中文分词,过滤停用词和同义词搜索也是很多人关心的问题。我也写了个动态更改停用词库和同义词库的工厂类,在这:
https://github.com/lgnlgn/stop4solr4.x 使用方式与上述接近,不再赘述。由于lucene的接口一直在变,因此github上的源码只适合4.4,如果是其他版本需要的在源码上检查是否OK。