`
wb284551926
  • 浏览: 539361 次
文章分类
社区版块
存档分类
最新评论

Solr的中英文分词实现(转载)

    博客分类:
  • solr
阅读更多

对于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服务于你的项目。

参考:

原文链接:http://thinkjet.me/solr-lucene-tokenizer-filter.html

分享到:
评论

相关推荐

    solr中文分词器技术

    中文分词技术(中文分词原理)词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的...

    solr+IK分词集成tomcat实现全文检索

    压缩包内含有solr+ik如何配置的详细介绍以及solr+ik的安装包,省去了自己去找地址下载的麻烦,经测试使用完全可以在电商电商项目中实现全文检索

    分词器ikanalyzerforsolr7.x.x

    分词器ik ikanalyzerforsolr7.x.x 适用于solr7.x.x版本的ik分词器,目前亲测7.2.1可用

    中文分词工具word-1.0,Java实现的中文分词组件多种基于词典的分词算法

    word分词是一个Java实现的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。 能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。 同时提供了Lucene...

    Solr权威指南-上卷

    本书立足全球视野,综合Solr技术的发展和应用、从业人员的学习曲线,以及中英文资料的供给情况,给自己设定了一个极高的目标:力争在内容的全面性、系统性、深浅度和实战性上概括所有的同类书。从完成的结果上来看,...

    Solr权威指南-下卷

    本书立足全球视野,综合Solr技术的发展和应用、从业人员的学习曲线,以及中英文资料的供给情况,给自己设定了一个极高的目标:力争在内容的全面性、系统性、深浅度和实战性上概括所有的同类书。从完成的结果上来看,...

    xmljava系统源码-IKAnalyzer2017_6_6_0:IK中文分词,兼容solr/lucene6.6.0,优化数字和英文搜索

    Solr作为搜索应用服务器,我们在使用过程中,不可避免的要使用中文搜索。 以下介绍solr的第三方分词器IKAnalyzer。 注:下面操作在Linux下执行,所添加的配置在windonws下依然有效。 运行环境 Solr:6.6.0 系统 : ...

    IK-Analyzer 分词器所需要的配置文件、扩展词典及停用词词典 完整包下载

    采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。 Linux下Solr4.10.4搜索引擎的安装与部署图文...

    word:Java分布式中文分词组件 - word分词

    word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过...

    IK-Analyzer 中文分词器必须依赖的 IKAnalyzer2012FF_u1.jar包 下载

    IKAnalyzer是一个开源的,基于java语言开发的轻... 采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。

    魂动罗java源码-jcseg:一个开源的分词器,增加同义词优化

    魂动罗java源码 Jcseg完整版本(源码, 词库, 帮助文档, 词库管理工具, jar文件)下载: 一. 关于jcseg: jcseg是使用Java开发的一个开源中文分词器,使用流行的mmseg算法...中英文同义词追加/同义词匹配 + 中文词条拼音追

    自己动手写搜索引擎(罗刚著).doc

    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 ...

    django haystack实现全文检索的示例代码

    3. 中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件 2. 什么是jieba? 很多的搜索引擎对中的支持不友好,jieba作为一个中文分词器就是加强

    Django haystack实现全文搜索代码示例

    中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件。 其他:Python 3.4.4, Django 1.8.3,Debian 4.2.6_3 二、配置说明 现在假设我们的项目叫做Project,有一个...

    jcseg-master.zip

    关键短语提取,关键句子提取和文章自动摘要等功能,并且提供了一个基于Jetty的web服务器,方便各大语言直接http调用,同时提供了最新版本的lucene、solr、elasticsearch、opensearch的搜索分词接口

    stopword:引用ysc备分

    ###Java分布式中文分词组件 - word分词####word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名...

    使用C sharp开发搜索引擎 C#搜索引擎开发实战 10-拼写检查(共41页).ppt

    使用C sharp开发搜索引擎 C#搜索引擎开发实战 31-Solr(共29页).ppt 使用C sharp开发搜索引擎 C#搜索引擎开发实战 32-SolrNet(共10页).ppt 使用C sharp开发搜索引擎 C#搜索引擎开发实战 插图(共8页).ppt

    Tantivy 是受 Apache Lucene 启发并用 Rust 编写的全文搜索引擎库

    它更接近Apache Lucene,而不是Elasticsearch或Apache Solr ,因为它不是现成的搜索引擎服务器,而是可用于构建此类搜索引擎的 crate。事实上,Tantivy 的灵感来自于 Lucene 的设计。基准以下基准会分解不同类型的...

Global site tag (gtag.js) - Google Analytics