我正在尝试向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
?
答案 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
}
}