wumai 发表于 2015-7-17 11:22:36

利用SOLR搭建企业搜索平台 之二(中文分词)

这篇文章,主要说的是 怎么在solr中加入中文分词,参考了一些文章,但是还是花了不少时间才搞出的。可能是大侠们太牛了,所以很多细节东西都没有写出来!但是要指出的是很多文章都是抄来抄去的!
入正题:
    在上面的一个文章中,已经使solr跑起来了,在上面的基础上,加入中文分词。我用的是paoding分词器!
1》请下好paoding分词器,下载地址:
http://code.google.com/p/paoding/downloads/list,在这里要非常感谢paoding作者:qieqie
在使用paoding的时候要注意:paoding的dic位置,也就是字典的位置,有两种办法解决:                     
1) 在系统环境变量中加入PAODING_DIC_HOME这个变量,值为paoding压缩包下面的dic的解压位置。
2)paoding-analysis.jar里面有个paoding-dic-home.properties文件,指定dic也可,但是要重新编译这个jar包,我采用的后面一种办法,只要每次固定好dic位置,部署还不是很不方便,设置环境变量我比较反感
2》建立文件



Java代码 http://lianj-lee.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf?clipboard=package%20com.yeedoo.slor.tokenizer%3B%0A%0Aimport%20java.io.Reader%3B%0Aimport%20java.util.Map%3B%0A%0Aimport%20net.paoding.analysis.analyzer.PaodingTokenizer%3B%0Aimport%20net.paoding.analysis.analyzer.TokenCollector%3B%0Aimport%20net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector%3B%0Aimport%20net.paoding.analysis.analyzer.impl.MostWordsTokenCollector%3B%0Aimport%20net.paoding.analysis.knife.PaodingMaker%3B%0A%0Aimport%20org.apache.lucene.analysis.TokenStream%3B%0Aimport%20org.apache.solr.analysis.BaseTokenizerFactory%3B%0A%0Apublic%20class%20ChineseTokenizerFactory%20extends%20BaseTokenizerFactory%20%7B%0A%09%0A%09%2F**%0A%09%20*%20%E6%9C%80%E5%A4%9A%E5%88%87%E5%88%86%20%E9%BB%98%E8%AE%A4%E6%A8%A1%E5%BC%8F%0A%09%20*%2F%0A%09public%20static%20final%20String%20MOST_WORDS_MODE%20%3D%20%22most-words%22%3B%0A%0A%09%2F**%0A%09%20*%20%E6%8C%89%E6%9C%80%E5%A4%A7%E5%88%87%E5%88%86%0A%09%20*%2F%0A%09public%20static%20final%20String%20MAX_WORD_LENGTH_MODE%20%3D%20%22max-word-length%22%3B%0A%0A%09private%20String%20mode%20%3D%20null%3B%0A%0A%09public%20void%20setMode(String%20mode)%20%7B%0A%09%09if%20(mode%20%3D%3D%20null%20%7C%7C%20MOST_WORDS_MODE.equalsIgnoreCase(mode)%20%7C%7C%20%22default%22.equalsIgnoreCase(mode))%20%7B%0A%09%09%09this.mode%20%3D%20MOST_WORDS_MODE%3B%0A%09%09%7D%20else%20if%20(MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode))%20%7B%0A%09%09%09this.mode%20%3D%20MAX_WORD_LENGTH_MODE%3B%0A%09%09%7D%20else%20%7B%0A%09%09%09throw%20new%20IllegalArgumentException(%22%E4%B8%8D%E5%90%88%E6%B3%95%E7%9A%84%E5%88%86%E6%9E%90%E5%99%A8Mode%E5%8F%82%E6%95%B0%E8%AE%BE%E7%BD%AE%3A%22%20%2B%20mode)%3B%0A%09%09%7D%0A%09%7D%0A%0A%09%40Override%0A%09public%20void%20init(Map%3CString%2CString%3E%20args)%20%7B%0A%09%09super.init(args)%3B%0A%09%09setMode(args.get(%22mode%22).toString())%3B%0A%09%7D%0A%0A%09public%20TokenStream%20create(Reader%20input)%20%7B%0A%09%09return%20new%20PaodingTokenizer(input%2C%20PaodingMaker.make()%2C%20createTokenCollector())%3B%0A%09%7D%0A%0A%09private%20TokenCollector%20createTokenCollector()%20%7B%0A%09%09if%20(MOST_WORDS_MODE.equals(mode))%0A%09%09%09return%20new%20MostWordsTokenCollector()%3B%0A%09%09if%20(MAX_WORD_LENGTH_MODE.equals(mode))%0A%09%09%09return%20new%20MaxWordLengthTokenCollector()%3B%0A%09%09throw%20new%20Error(%22never%20happened%22)%3B%0A%09%7D%0A%09%0A%7D
[*]package com.yeedoo.slor.tokenizer;
[*]
[*]import java.io.Reader;
[*]import java.util.Map;
[*]
[*]import net.paoding.analysis.analyzer.PaodingTokenizer;
[*]import net.paoding.analysis.analyzer.TokenCollector;
[*]import net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector;
[*]import net.paoding.analysis.analyzer.impl.MostWordsTokenCollector;
[*]import net.paoding.analysis.knife.PaodingMaker;
[*]
[*]import org.apache.lucene.analysis.TokenStream;
[*]import org.apache.solr.analysis.BaseTokenizerFactory;
[*]
[*]public class ChineseTokenizerFactory extends BaseTokenizerFactory {
[*]
[*]    /**
[*]   * 最多切分 默认模式
[*]   */
[*]    public static final String MOST_WORDS_MODE = "most-words";
[*]
[*]    /**
[*]   * 按最大切分
[*]   */
[*]    public static final String MAX_WORD_LENGTH_MODE = "max-word-length";
[*]
[*]    private String mode = null;
[*]
[*]    public void setMode(String mode) {
[*]      if (mode == null || MOST_WORDS_MODE.equalsIgnoreCase(mode) || "default".equalsIgnoreCase(mode)) {
[*]            this.mode = MOST_WORDS_MODE;
[*]      } else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) {
[*]            this.mode = MAX_WORD_LENGTH_MODE;
[*]      } else {
[*]            throw new IllegalArgumentException("不合法的分析器Mode参数设置:" + mode);
[*]      }
[*]    }
[*]
[*]    @Override
[*]    public void init(Map args) {
[*]      super.init(args);
[*]      setMode(args.get("mode").toString());
[*]    }
[*]
[*]    public TokenStream create(Reader input) {
[*]      return new PaodingTokenizer(input, PaodingMaker.make(), createTokenCollector());
[*]    }
[*]
[*]    private TokenCollector createTokenCollector() {
[*]      if (MOST_WORDS_MODE.equals(mode))
[*]            return new MostWordsTokenCollector();
[*]      if (MAX_WORD_LENGTH_MODE.equals(mode))
[*]            return new MaxWordLengthTokenCollector();
[*]      throw new Error("never happened");
[*]    }
[*]
[*]}
package com.yeedoo.slor.tokenizer;import java.io.Reader; import java.util.Map;import net.paoding.analysis.analyzer.PaodingTokenizer; import net.paoding.analysis.analyzer.TokenCollector; import net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector; import net.paoding.analysis.analyzer.impl.MostWordsTokenCollector; import net.paoding.analysis.knife.PaodingMaker;import org.apache.lucene.analysis.TokenStream; import org.apache.solr.analysis.BaseTokenizerFactory;public class ChineseTokenizerFactory extends BaseTokenizerFactory {/*** 最多切分 默认模式*/ public static final String MOST_WORDS_MODE = "most-words";/*** 按最大切分*/ public static final String MAX_WORD_LENGTH_MODE = "max-word-length";private String mode = null;public void setMode(String mode) { if (mode == null || MOST_WORDS_MODE.equalsIgnoreCase(mode) || "default".equalsIgnoreCase(mode)) { this.mode = MOST_WORDS_MODE; } else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) { this.mode = MAX_WORD_LENGTH_MODE; } else { throw new IllegalArgumentException("不合法的分析器Mode参数设置:" + mode); } }@Override public void init(Map args) { super.init(args); setMode(args.get("mode").toString()); }public TokenStream create(Reader input) { return new PaodingTokenizer(input, PaodingMaker.make(), createTokenCollector()); }private TokenCollector createTokenCollector() { if (MOST_WORDS_MODE.equals(mode)) return new MostWordsTokenCollector(); if (MAX_WORD_LENGTH_MODE.equals(mode)) return new MaxWordLengthTokenCollector(); throw new Error("never happened"); }}
将该文件打包,如果你不愿打包,请到附件里面下吧。
请将两个jar,一个是这个,还有一个是 paoding-analysis.jar 放到tomcat的webapps"solr"WEB-INF"lib"下
3》更改schema.xml文件,使分词器起到作用。如果你看过前面一个文章,schema.xml的具体位置在c:"solr-tomcat"solr"conf"下面。
更改内容为:



Xml代码 http://lianj-lee.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf?clipboard=%3CfieldType%20name%3D%22text%22%20class%3D%22solr.TextField%22%20positionIncrementGap%3D%22100%22%3E%0A%20%20%20%20%20%20%3Canalyzer%20type%3D%22index%22%3E%0A%20%20%20%20%20%20%20%20%3C!--%3Ctokenizer%20class%3D%22solr.WhitespaceTokenizerFactory%22%2F%3E--%3E%0A%20%20%20%20%20%20%20%20%3Ctokenizer%20class%3D%22com.yeedoo.slor.tokenizer.ChineseTokenizerFactory%22%20mode%3D%22most-words%22%2F%3E%0A%20%20%20%20%20%20%C2%B7%C2%B7%C2%B7%20%C2%B7%C2%B7%C2%B7%0A%20%20%20%20%20%20%3C%2Fanalyzer%3E%0A%20%20%20%20%20%20%3Canalyzer%20type%3D%22query%22%3E%0A%20%20%20%20%20%20%20%20%20%3C!--%3Ctokenizer%20class%3D%22solr.WhitespaceTokenizerFactory%22%2F%3E--%3E%0A%20%20%20%20%20%20%20%20%20%3Ctokenizer%20%20%20%20%20class%3D%22com.yeedoo.slor.tokenizer.ChineseTokenizerFactory%22%20mode%3D%22most-words%22%2F%3E%20%0A%20%20%20%20%20%20%20%20%C2%B7%C2%B7%C2%B7%20%C2%B7%C2%B7%C2%B7%0A%20%20%20%20%20%20%3C%2Fanalyzer%3E%0A%3C%2FfieldType%3E
[*]
[*]      
[*]         
[*]         
[*]      ··· ···
[*]      
[*]      
[*]         
[*]            
[*]      ··· ···
[*]      
[*]
                              ··· ···                                          ··· ···         
里面的为需要更改的内容
4》重启你的tomcat ,ok!
附: Solr建立索引和对关键词进行查询都得对字串进行分词,在向索引库中添加全文检索类型的索引的时候,Solr会首先用空格进行分词,然后把分词结果依次使用指定的过滤器进行过滤,最后剩下的结果才会加入到索引库中以备查询。分词的顺序如下:
索引
1:空格whitespaceTokenize
2:过滤词StopFilter
3:拆字WordDelimiterFilter
4:小写过滤LowerCaseFilter
5:英文相近词EnglishPorterFilter
6:去除重复词RemoveDuplicatesTokenFilter
查询
1:查询相近词
2:过滤词
3:拆字
4:小写过滤
5:英文相近词
6:去除重复词
以上是针对英文,中文的除了空格,其他都类似
页: [1]
查看完整版本: 利用SOLR搭建企业搜索平台 之二(中文分词)