对于Solr应该不需要过多介绍了,强大的功能也是都体验过了,但是solr一个较大的问题就是分词问题,特别是中英文的混合分词,处理起来非常棘手。 虽然solr自带了支持中文分词的cjk,但是其效果实在不好,所以solr要解决的一个问题就是中文分词问题,这里推荐的方案是利用ik进行分词。
ik是较早作中文分词的工具,其效果也是得到多数用户认同。但是现在作者似乎更新缓慢,对于最新的solr4.4支持不好,最新的更新也停留在2012年。
虽然不支持4.4版本(这也不是作者的错,solr的lucene的新版本接口都进行了修改,除非修改实现不然就没法向下兼容),但是我们也有办法的,我们可以利用他的分词工具自己封装一个TokenizerFactory,通过实现最新的4.4接口就可以让solr4.4用上ik了。
首先就是就在下载ik的原码,最新版是 然后自己实现一个TokenizerFactory:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package org.wltea.analyzer.lucene;
import java.io.Reader;
import java.util.Map;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.util.AttributeSource.AttributeFactory;
public class IKAnalyzerTokenizerFactory extends TokenizerFactory{
private boolean useSmart;
public boolean useSmart() {
return useSmart;
}
public void setUseSmart( boolean useSmart) {
this .useSmart = useSmart;
}
public IKAnalyzerTokenizerFactory(Map<String, String> args) {
super (args);
assureMatchVersion();
this .setUseSmart(args.get( "useSmart" ).toString().equals( "true" ));
}
@Override
public Tokenizer create(AttributeFactory factory, Reader input) {
Tokenizer _IKTokenizer = new IKTokenizer(input , this .useSmart);
return _IKTokenizer;
}
} |
然后重新打包jar放到solr的执行lib里,同时新建一个fieldType
1
2
3
4
5
6
7
8
|
< fieldType name = "text_ik" class = "solr.TextField" >
< analyzer type = "index" >
< tokenizer class = "org.wltea.analyzer.lucene.IKAnalyzerTokenizerFactory" useSmart = "false" />
</ analyzer >
< analyzer type = "query" >
< tokenizer class = "org.wltea.analyzer.lucene.IKAnalyzerTokenizerFactory" useSmart = "true" />
</ analyzer >
</ fieldType >
|
测试一下我们新的分词器:
// 输入 移动互联网 // 输出 移动,互联网,互联,联网
从结果来看,其效果还是比较不错的。
搞定了中文我们需要搞定英文 英文简单的分词是按照空格,标点,stopword等来分词。 比如I'm coding一般可以分词为I'm, coding或者I, m, coding。一般情况下这样也是可以接受的,但是如果用户输入code,是否应该搜到结果呢,如果要搜到该结果,那么我们需要处理我们的英文分词。
这里提供一种简单的实现,就是采用NGramFilterFactory,该过滤器简单的按照长度对词进行切分,该过滤器有两个参数minGramSize和maxGramSize,分别表示最小和最大的切分长度,默认是1和2。
1
2
3
4
|
< analyzer >
< tokenizer class = "solr.StandardTokenizerFactory" />
< filter class = "solr.NGramFilterFactory" minGramSize = "1" maxGramSize = "4" />
</ analyzer >
|
比如设置(min,max)为(3,5),我们上面的句子“I'm coding”会得到以下的结果:
I'm,cod,codi,codin,coding,odi,odin,oding,din,ding,ing
当然这里也会有问题,就是小于3个词长的都会被过滤调,特别是中文和英文采用的是同一词长处理,如果min设为3,那么像我,我们这样的都会被过滤,解决办法就是min设为1,这样的结果就是会大大增加索引记录。影响检索速度。好处就是可以实现字母级别的匹配,然后通过设置匹配度阔值提升了搜索质量。
分别处理完了中文和英文,那么就要混合中英文处理了
-
方案一是使用StandardTokenizerFactory和NGramFilterFactory,加上辅助的StopFilterFactory和LowerCaseFilterFactory等过滤器处理。也就是中文默认是按字逐个分开,当然前提是NGramFilterFactory的minGramSize要设置为1。
-
方案二则是IKAnalyzerTokenizerFactory和NGramFilterFactory,通过ik实现对词的索引,然后在通过ngram进行长度分割。即在方案一的基础上增加对词的索引,提升索引质量。
-
方案一和方案二如果还不够和谐的,那么我们还有个办法就是自定义的反感三,所谓自定义,自己写个tokenizer或者filter不就可以了,而且这一点也不复杂,这里就不细说了,有机会再专门写一个。
最后来个整合的配置参考一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< fieldType name = "text_ik" class = "solr.TextField" positionIncrementGap = "100" >
< analyzer type = "index" >
< tokenizer class = "org.wltea.analyzer.lucene.IKAnalyzerTokenizerFactory" useSmart = "false" />
< filter class = "solr.StopFilterFactory" ignoreCase = "true" words = "stopwords.txt" />
< filter class = "solr.LowerCaseFilterFactory" />
< filter class = "solr.NGramFilterFactory" minGramSize = "1" maxGramSize = "20" />
</ analyzer >
< analyzer type = "query" >
< tokenizer class = "org.wltea.analyzer.lucene.IKAnalyzerTokenizerFactory" useSmart = "true" />
< filter class = "solr.StopFilterFactory" ignoreCase = "true" words = "stopwords.txt" />
< filter class = "solr.SynonymFilterFactory" synonyms = "synonyms.txt" ignoreCase = "true" expand = "true" />
< filter class = "solr.LowerCaseFilterFactory" />
< filter class = "solr.NGramFilterFactory" minGramSize = "1" maxGramSize = "10" />
</ analyzer >
</ fieldType >
|
这里所提出的并不是最优的方案,或者说可能是比较傻瓜化的方案,但是solr的优势就是自由,你可以自己组合各种tokenizer和filter来实现你要的效果,或者干脆自己去实现tokenizer和filter,然后让强大的solr服务于你的项目。
参考:
相关推荐
中文分词技术(中文分词原理)词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的...
压缩包内含有solr+ik如何配置的详细介绍以及solr+ik的安装包,省去了自己去找地址下载的麻烦,经测试使用完全可以在电商电商项目中实现全文检索
分词器ik ikanalyzerforsolr7.x.x 适用于solr7.x.x版本的ik分词器,目前亲测7.2.1可用
word分词是一个Java实现的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。 能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。 同时提供了Lucene...
本书立足全球视野,综合Solr技术的发展和应用、从业人员的学习曲线,以及中英文资料的供给情况,给自己设定了一个极高的目标:力争在内容的全面性、系统性、深浅度和实战性上概括所有的同类书。从完成的结果上来看,...
本书立足全球视野,综合Solr技术的发展和应用、从业人员的学习曲线,以及中英文资料的供给情况,给自己设定了一个极高的目标:力争在内容的全面性、系统性、深浅度和实战性上概括所有的同类书。从完成的结果上来看,...
Solr作为搜索应用服务器,我们在使用过程中,不可避免的要使用中文搜索。 以下介绍solr的第三方分词器IKAnalyzer。 注:下面操作在Linux下执行,所添加的配置在windonws下依然有效。 运行环境 Solr:6.6.0 系统 : ...
采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。 Linux下Solr4.10.4搜索引擎的安装与部署图文...
word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过...
IKAnalyzer是一个开源的,基于java语言开发的轻... 采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。
魂动罗java源码 Jcseg完整版本(源码, 词库, 帮助文档, 词库管理工具, jar文件)下载: 一. 关于jcseg: jcseg是使用Java开发的一个开源中文分词器,使用流行的mmseg算法...中英文同义词追加/同义词匹配 + 中文词条拼音追
5.1.1 Lucene 中的中文分词 91 5.1.2 Lietu中文分词的使用 92 5.1.3 中文分词的原理 92 5.1.4 查找词典算法 95 5.1.5 最大概率分词方法 98 5.1.6 新词发现 101 5.1.7 隐马尔可夫模型 102 5.2 语法解析树 104 5.3 ...
3. 中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件 2. 什么是jieba? 很多的搜索引擎对中的支持不友好,jieba作为一个中文分词器就是加强
中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件。 其他:Python 3.4.4, Django 1.8.3,Debian 4.2.6_3 二、配置说明 现在假设我们的项目叫做Project,有一个...
关键短语提取,关键句子提取和文章自动摘要等功能,并且提供了一个基于Jetty的web服务器,方便各大语言直接http调用,同时提供了最新版本的lucene、solr、elasticsearch、opensearch的搜索分词接口
###Java分布式中文分词组件 - word分词####word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名...
使用C sharp开发搜索引擎 C#搜索引擎开发实战 31-Solr(共29页).ppt 使用C sharp开发搜索引擎 C#搜索引擎开发实战 32-SolrNet(共10页).ppt 使用C sharp开发搜索引擎 C#搜索引擎开发实战 插图(共8页).ppt
它更接近Apache Lucene,而不是Elasticsearch或Apache Solr ,因为它不是现成的搜索引擎服务器,而是可用于构建此类搜索引擎的 crate。事实上,Tantivy 的灵感来自于 Lucene 的设计。基准以下基准会分解不同类型的...