4

我正在尝试将一个添加CharFilter到我的StandardAnalyzer. 我的意图是从我索引的所有文本中去掉标点符号;例如,我希望 PrefixQuery "pf" 匹配 "PF Chang's" 或 "zaras" 匹配 "Zara's"。

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

但是,实际上几乎不可能将 aCharFilter插入分析仪!

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

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

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

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

我在这里错过了什么明显的东西吗?如何修改 aStandardAnalyzer以使用自定义CharFilter

4

1 回答 1

5

目的是让您覆盖Analyzer,而不是StandardAnalyzer. 想法是您永远不应该将 Analyzer 实现子类化(这里有一些讨论)。虽然分析器实现非常简单,但将 CharFilter 添加到实现与 StandardAnalyzer 相同的标记器/过滤器链的分析器中看起来像:

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
    }
}
于 2013-06-12T17:42:13.657 回答