我正在尝试将 CharFilter
添加到我的 StandardAnalyzer
。我的意图是从我索引的所有文本中删除标点符号;例如,我想要一个前缀查询“pf”来匹配“P.F. Chang's”或“zaras”来匹配“Zara's”。
这里最简单的攻击计划似乎是在分析之前过滤掉所有标点符号。根据 Analyzer package documentation ,这意味着我应该使用 CharFilter
。
但是,实际上将 CharFilter
插入分析器似乎几乎是不可能的!
Analyzer.initReader 的 JavaDoc说“如果您想插入一个 CharFilter,请覆盖它”。
如果我的代码扩展 Analyzer,我可以扩展 initReader 但我不能委托(delegate)抽象 createComponents到我的基础 StandardAnalyzer,因为它受到保护。我不能委托(delegate) tokenStream到我的基本分析器,因为它是最终的。所以 Analyzer 的子类似乎不能使用另一个 Analyzer 来完成它的肮脏工作。
AnalyzerWrapper
类似乎非常适合我想要的东西!我可以提供一个基础分析器,只覆盖我想要的部分。除了……initReader已经被覆盖以委托(delegate)给基本分析器,并且这个覆盖是“最终的”!真可惜!
我想我可以将我的 Analyzer
放在 org.apache.lucene.analyzers
包中,然后我可以访问 protected createComponents
方法,但这似乎是一种绕过我真正应该使用的公共(public) API 的令人作呕的 hacky 方法。
我是不是漏掉了一些明显的东西?我如何修改 StandardAnalyzer
以使用自定义 CharFilter
?
最佳答案
目的是让您覆盖 Analyzer
,而不是 StandardAnalyzer
。这个想法是你永远不应该子类化 Analyzer 实现(那里的一些讨论 here )。不过,分析器的实现非常简单,将 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
}
}
关于java - 将 CharFilter 与 Lucene 4.3.0 的 StandardAnalyzer 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17071300/