lucene analyzer tokenizer(分詞) 的工作記錄
因為最近必須對lucene 的特殊字元進行搜尋(lucene 分詞時
預設是排除特殊字元的, 除了WhiteSpaceAnalyzer), 所以研
究了lucene 分詞的原始碼.
記錄如下:
先說說StandardAnalyzer
StandardAnalyzer extends 自 StopwordAnalyzerBase
當 writer.add(doc) 之後, 會先進入 Analyzer
(所有Analyzer的父類)
然後再根據所選擇的 Analyzer 進入該 Analyzer 執行
CreateComponents 這個函數
CreateComponents 在每一個子類的Analyzer都有不同的實
現方式
例如, 其中StandardAnalyzer 的 CreateComponents 代碼
如下:
@Override
protected TokenStreamComponents createComponents
(final String fieldName, final Reader reader) {
final StandardTokenizer src =
new StandardTokenizer(matchVersion, reader);
src.setMaxTokenLength(maxTokenLength);
TokenStream tok = new StandardFilter(matchVersion, src);
tok = new LowerCaseFilter(matchVersion, tok);
tok = new StopFilter(matchVersion, tok, stopwords);
return new TokenStreamComponents(src, tok) {
@Override
protected void setReader(final Reader reader)
throws IOException {
src.setMaxTokenLength(StandardAnalyzer.this.maxTokenLength);
super.setReader(reader);
}
};
}
由以上代碼可看出StandardAnalyzer 進行 StandardTokenizer
/StandardFilter/LowerCaseFilter/StopFilter 等程序
再看看WhiteSpaceAnalyzer
@Override
protected TokenStreamComponents createComponents
(final String fieldName,
final Reader reader) {
return new TokenStreamComponents(new
WhitespaceTokenizer(matchVersion, reader));
}
以上可看出 WhiteSpaceAnalyzer, 它的 CreateComponents,
就只有進行WhitespaceTokenizer而己.
以上的StandardTokenizer是進行分詞的程序, 看看它做些什麼
StandardTokenizer中有一個init的函數, 執行
StandardTokenizerImpl
StandardTokenizerImpl 會實際對全文進行分詞. 這個函數相
當複雜, 很難理解, 我只理解一小部分
其中
private static final char [] ZZ_CMAP =
zzUnpackCMap(ZZ_CMAP_PACKED);
ZZ_CMAP 存放每一個字元一個值, 用來判斷該字元是分詞時要納入的
正常值,或是不納入的分割字元.
例如 35是#的ascii內碼
當 ZZ_CMAP[35]=0 時, 代表#在分詞時會被排除"#abc #def ghi" 分詞後=>abc, def, ghi
當 ZZ_CMAP[35]='~' (十進位為126, 為何是126?不解) 時,
代表#在分詞時會被納入"#abc #def ghi" 分詞後=>#abc, #def, ghi
所以想讓#被含在分詞中, 只要 ZZ_CMAP[35]='~' 即可