使用CharFilter和Lucene 4.3.0的StandardAnalyzer

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

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

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

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

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

有一个AnalyzerWrapper类似乎是我想要的完美! 我可以提供一个基础分析器,只覆盖我想要的部分。 除了… initReader已经被覆盖以委托给基础分析器,并且这个覆盖是“最终的”! 坏消息!

我想我可以让我的Analyzerorg.apache.lucene.analyzers包中然后我可以访问受保护的createComponents方法,但这似乎是一种令人厌恶的hacky方式绕过我真正应该使用的公共API。

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

目的是为了覆盖Analyzer而不是StandardAnalyzer 。 我们的想法是你永远不应该对Analyzer实现进行子类化( 这里有一些讨论)。 分析器实现非常简单,并且向实现与StandardAnalyzer相同的标记器/filter链的分析器添加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 } }