Lucene分析器的实现。 Lucene(分词)过滤器TokenFilter类,以及继承它的子类的实现类。 TokenFilter类的继承关系,如图所示: TokenFilter是一个抽象类,定义了对一个经过分词(Tokenizer)后的TokenStream进行过滤的功能,它的源代码如下所示: package org.apache.lucene.analysis; import java.io.IOException; public abstract class TokenFilter extends TokenStream { protected TokenFilter(TokenStream input) { public void close() throws IOException { ChineseFilter中文过滤器类: package org.apache.lucene.analysis.cn; import java.util.Hashtable; // 中文过滤器,包含了含有外文字符的情况,因为中文搜索的关键字可能是:中文+外文 public final class ChineseFilter extends TokenFilter { // 这里给出了英文的终止词汇,如果直接调用根本对中文没有过滤作用,或者也可以在此添加终止词汇,比如:“也、了、啊、吧、呵……”等等一些助词叹词,因为这些词语对于检索没有意义
// 构造函数,初始化一个终止词汇表 (过滤掉的词汇) public ChineseFilter(TokenStream in) { stopTable = new Hashtable(STOP_WORDS.length); // 如果stopTable为空,说明该过滤类根本没有进行过滤,直接将读入的词条(Token)返回 public final Token next() throws java.io.IOException { for (Token token = input.next(); token != null; token = input.next()) { // 这里,如果chineseChar是单个字,则Character.getType(chineseChar)返回的类型值为5;大写英文字符类型值为1,小写字符类型值为2 case Character.LOWERCASE_LETTER: // 如果英文词条不是单个字符 // 如果中文的过滤词汇表中是单个字的形式,则若是一个词汇中有一个字出现在stopTable中,那么整个词条都被过滤掉了。这是不合理的;所以只要把stopTable设置为空就可以实现,即不对分词的词条进行过滤 return token; } } } 再看一个限制词条长度的过滤器类:
import java.io.IOException; // 词条过长或者过短,则过滤掉 final int min; // 构造函数,初始化此条长度上限和下限 // 返回长度在min与max之间的词条 return null; 可见,过滤器的目的就是对分词获得的词条的一些属性信息进行过滤,原则是:这些属性信息对检索没有实际意义。通过阅读标准过滤器类,再综合各种需要,我们就能根据自己的需要实现词条的过滤。Lucene包里给出的标准过滤器类。其实是对英文字符过滤的的,源代码如下: package org.apache.lucene.analysis.standard; import org.apache.lucene.analysis.*; public final class StandardFilter extends TokenFilter public StandardFilter(TokenStream in) { // APOSTROPHE、ACRONYM等都是在一个常量接口类StandardTokenizerConstants里定义的常量,分别代表在过滤中可能要对其进行处理的字符 private static final String APOSTROPHE_TYPE = tokenImage[APOSTROPHE]; if (t == null) String text = t.termText(); // 英文中的 's或'S对检索意义不大,可以删除掉 } else if (type == ACRONYM_TYPE) { // 对“圆点”进行处理,直接把出现的“圆点”删除掉,保留其它字符 } else { 常量接口类StandardTokenizerConstants 定义如下: package org.apache.lucene.analysis.standard; public interface StandardTokenizerConstants { int EOF = 0; int DEFAULT = 0; String[] tokenImage = { 还有一个org.apache.lucene.analysis.StopFilter类,和ChineseFilter类的实现很相似,只是这里把过滤字符列表是初始化一个StopFilter过滤器的时候指定的,而且该类实现了对过滤字符类表中字符进行转换的功能。 我感觉,最应该好好研究的是关于同义词的过滤问题。Lucene包中给了一个org.apache.lucene.index.memory.SynonymTokenFilter过滤类,比较复杂,因为这里面涉及到了一个重要的类:org.apache.lucene.index.memory.SynonymMap。通过研究对英文中同义词的过滤,来考虑中文同义词过滤的问题。 |