如何基于Lucene StandardAnalyzer定制可过滤指定词汇的自定义分析器
Lucene自定义分析器实现(基于StandardAnalyzer+指定词汇过滤)
针对Lucene 8.10.1版本,你不需要完全从零实现Analyzer,只需复用StandardAnalyzer的核心逻辑,再追加自定义词汇过滤环节即可。以下是具体实现方案:
核心思路
StandardAnalyzer本身已经封装了标准分词、小写转换、默认停用词过滤等逻辑,我们可以在它生成的TokenStream之后,插入自定义的停用词过滤器,或者手动构建与StandardAnalyzer一致的Token链,再加入自定义过滤规则,两种方式任选其一。
方案一:复用StandardAnalyzer组件
直接复用StandardAnalyzer的Tokenizer和基础TokenStream,在其后追加自定义词汇过滤:
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.standard.StandardTokenizer; import org.apache.lucene.analysis.stop.StopFilter; import org.apache.lucene.analysis.util.CharArraySet; public class CustomFilteringAnalyzer extends Analyzer { private final CharArraySet customStopWords; private final StandardAnalyzer standardAnalyzer; // 构造方法传入要过滤的词汇集合 public CustomFilteringAnalyzer(CharArraySet customStopWords) { this.customStopWords = customStopWords; this.standardAnalyzer = new StandardAnalyzer(); } @Override protected TokenStreamComponents createComponents(String fieldName) { // 获取StandardAnalyzer的原生分词组件 TokenStreamComponents standardComponents = standardAnalyzer.createComponents(fieldName); StandardTokenizer tokenizer = (StandardTokenizer) standardComponents.getTokenizer(); // 在StandardAnalyzer的TokenStream后添加自定义词汇过滤 TokenStream filteredStream = new StopFilter(standardComponents.getTokenStream(), customStopWords); return new TokenStreamComponents(tokenizer, filteredStream); } // 复用StandardAnalyzer的字符处理逻辑 @Override protected Reader initReader(String fieldName, Reader reader) { return standardAnalyzer.initReader(fieldName, reader); } }
方案二:手动构建Token链(灵活控制逻辑)
如果不需要StandardAnalyzer的默认停用词,可手动构建与它逻辑一致的Token链,再加入自定义过滤:
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.core.LowerCaseFilter; import org.apache.lucene.analysis.standard.StandardFilter; import org.apache.lucene.analysis.standard.StandardTokenizer; import org.apache.lucene.analysis.stop.StopFilter; import org.apache.lucene.analysis.util.CharArraySet; public class CustomFilteringAnalyzer extends Analyzer { private final CharArraySet customStopWords; public CustomFilteringAnalyzer(CharArraySet customStopWords) { this.customStopWords = customStopWords; } @Override protected TokenStreamComponents createComponents(String fieldName) { // 构建与StandardAnalyzer一致的基础Token链 StandardTokenizer tokenizer = new StandardTokenizer(); TokenStream stream = new StandardFilter(tokenizer); stream = new LowerCaseFilter(stream); // 加入自定义词汇过滤 stream = new StopFilter(stream, customStopWords); return new TokenStreamComponents(tokenizer, stream); } }
使用示例
import org.apache.lucene.analysis.util.CharArraySet; import java.util.Arrays; public class Main { public static void main(String[] args) { // 定义需要过滤的词汇集合(CharArraySet是Lucene推荐的高性能集合类型) CharArraySet customStopWords = new CharArraySet( Arrays.asList("敏感词", "测试词汇", "冗余内容"), false // 是否忽略大小写,根据业务需求调整 ); // 创建自定义分析器 CustomFilteringAnalyzer analyzer = new CustomFilteringAnalyzer(customStopWords); // 后续可用于索引配置 // IndexWriterConfig config = new IndexWriterConfig(analyzer); // ... } }
关键说明
CharArraySet是Lucene专门优化的字符串集合,性能优于普通Java集合,建议优先使用。StopFilter是Lucene内置的停用词过滤器,直接传入自定义词汇集合即可实现过滤,无需重复造轮子。- 两种方案都能保证基础分词逻辑与
StandardAnalyzer完全一致,仅追加自定义过滤规则,避免破坏原有功能。
内容的提问来源于stack exchange,提问作者lazyass
相关产品推荐
相关产品推荐

