分詞器是 Lucene 索引與搜索質量的生命線。本文深入剖析 Analyzer 核心架構、內置分詞器適用場景、中文分詞器(IK/SmartCN)集成實戰、以及自定義分詞器開發模式。
Analyzer
└─ createComponents(fieldName) → TokenStreamComponents
├─ Tokenizer (字符流 → Token 流) -- 分詞入口
└─ TokenFilter[] (Token 流 → Token 流) -- 過濾鏈:停用詞、小寫、詞幹、同義詞
Tokenizer extends TokenStream:incrementToken() 逐個產出 CharTermAttribute、OffsetAttribute、PositionIncrementAttributeTokenFilter extends TokenStream:裝飾器模式包裝上游 TokenStreamAnalyzer:線程安全,每次調用 tokenStream() 返回新 TokenStreamComponents| 分詞器 | Tokenizer | Filter 鏈 | 適用場景 |
|---|---|---|---|
StandardAnalyzer | StandardTokenizer | LowerCase + StopFilter | 通用英文、標準 Unicode 文本 |
SimpleAnalyzer | LetterTokenizer | LowerCase | 純字母文本、教學演示 |
WhitespaceAnalyzer | WhitespaceTokenizer | 無 | 空格分隔、日誌、代碼 |
KeywordAnalyzer | KeywordTokenizer | 無 | 整體作為單詞(ID、郵編、產品號) |
PatternAnalyzer | PatternTokenizer | LowerCase + StopFilter | 正則分隔(CSV、特定分隔符) |
<dependency>
<groupId>com.github.magese</groupId>
<artifactId>ik-analyzer</artifactId>
<version>8.11.0</version> <!-- 對應 Lucene 版本 -->
</dependency>
| 模式 | 特點 | 適用場景 |
|---|---|---|
IKAnalyzer(true) 智能分詞 | 語義理解、歧義消解、命名實體識別 | 搜索查詢、智能推薦 |
IKAnalyzer(false) 最細粒度 | 窮舉所有可能詞組、召回率最高 | 索引構建、全文檢索 |
@Configuration
public class LuceneConfig {
@Bean
public Analyzer ikSmartAnalyzer() {
return new IKAnalyzer(true); // 智能模式
}
@Bean
public Analyzer ikMaxWordAnalyzer() {
return new IKAnalyzer(false); // 最細粒度
}
}
// 索引時:最細粒度,保證召回
Document doc = new Document();
doc.add(new TextField("content", article.getContent(), Field.Store.YES));
writer.addDocument(doc, ikMaxWordAnalyzer);
// 查詢時:智能分詞,提升精準度
QueryParser parser = new QueryParser("content", ikSmartAnalyzer);
Query query = parser.parse(userKeyword);
TopDocs hits = searcher.search(query, 10);
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>8.11.0</version>
</dependency>
// 直接使用,內置隱馬模型詞典
Analyzer smartCN = new SmartChineseAnalyzer();
// 索引查詢統一使用,無需雙模式
對比: IK 詞典豐富、支援自定義詞典、雙模式靈活;SmartCN 零配置、Jar 包小、適合輕量級應用。
public class SkuAnalyzer extends Analyzer {
@Override
protected TokenStreamComponents createComponents(String fieldName) {
// 1. 自定義 Tokenizer:按特定分隔符切分,保持 SKU 整體
Tokenizer tokenizer = new PatternTokenizer(
Pattern.compile("[\\s,;|]+"), -1); // 保持 SKU 如 "SKU-001-A" 不拆分
// 2. Filter 鏈:小寫 + 停用詞 + 自定義同義詞擴展
TokenStream stream = new LowerCaseFilter(tokenizer);
stream = new StopFilter(stream, StandardAnalyzer.STOP_WORDS_SET);
stream = new SynonymGraphFilter(stream, synonymMap); // 同義詞:手機 → phone, mobile
return new TokenStreamComponents(tokenizer, stream);
}
}
public static void analyze(Analyzer analyzer, String text) throws IOException {
try (TokenStream stream = analyzer.tokenStream("test", new StringReader(text))) {
stream.reset();
CharTermAttribute term = stream.addAttribute(CharTermAttribute.class);
OffsetAttribute offset = stream.addAttribute(OffsetAttribute.class);
PositionIncrementAttribute pos = stream.addAttribute(PositionIncrementAttribute.class);
System.out.println("=== " + analyzer.getClass().getSimpleName() + " ===");
while (stream.incrementToken()) {
System.out.printf("Term: %-15s Start: %d End: %d PosInc: %d%n",
term.toString(), offset.startOffset(), offset.endOffset(), pos.getPositionIncrement());
}
stream.end();
}
}
PositionIncrement)影響短語查詢 → 同義詞過濾器需正確設置lucene-analyzers-* 版本必須與 lucene-core 完全一致分詞器是搜索質量的第一道關卡。中文場景首選 IK Analyzer 雙模式策略(索引最細、查詢智能),輕量級選 SmartCN。自定義分詞器遵循「Tokenizer 切分 + Filter 鏈豐富」組合模式,單例複用 Analyzer 實例。