将CharFilter与Lucene 4.3.0的StandardAnalyzer配合使用

时间:2013-06-12 17:07:49

标签: java lucene

我正在尝试向CharFilter添加StandardAnalyzer。我的目的是从我索引的所有文本中删除标点符号;例如,我想要一个PrefixQuery“pf”匹配“P.F. Chang's”或“zaras”来匹配“Zara's”。

这里最简单的攻击计划似乎是在分析之前过滤掉所有标点符号。根据{{​​3}},这意味着我应该使用CharFilter

然而,实际上几乎不可能将CharFilter插入分析仪中!

Analyzer package documentation的JavaDoc说“如果要插入CharFilter,请覆盖它。”

如果我的代码扩展了Analyzer,我可以扩展initReader但是我不能将abstract Analyzer.initReader委托给我的基本StandardAnalyzer,因为它受到保护。我不能将createComponents委托给我的基础分析器,因为它是最终的。所以Analyzer的子类似乎不能使用另一个Analyzer来完成它的脏工作。

有一个AnalyzerWrapper课程似乎非常适合我想要的课程!我可以提供一个基础分析器,只覆盖我想要的部分。除了...... tokenStream已经被覆盖以委托给基础分析器,并且这个覆盖是“最终的”!无赖!

我想我可以将Analyzer放在org.apache.lucene.analyzers包中,然后我可以访问受保护的createComponents方法,但这似乎是一种令人作呕的方式绕过公共API我真的应该使用它。

我错过了一些明显的东西吗?如何修改StandardAnalyzer以使用自定义CharFilter

1 个答案:

答案 0 :(得分:5)

您的目的是覆盖Analyzer,而不是StandardAnalyzer。我们的想法是你永远不应该对Analyzer实现进行子类化(对here的一些讨论)。分析器实现非常简单,并且向实现与StandardAnalyzer相同的标记器/过滤器链的分析器添加CharFilter将类似于:

public final class MyAnalyzer {
    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
        final StandardTokenizer src = new StandardTokenizer(matchVersion, reader);
        TokenStream tok = new StandardFilter(matchVersion, src);
        tok = new LowerCaseFilter(matchVersion, tok);
        tok = new StopFilter(matchVersion, tok, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
        return new TokenStreamComponents(src, tok);
    }

    @Override
    protected Reader initReader(String fieldName, Reader reader) {
        //return your CharFilter-wrapped reader here
    }
}