Lucene中处理中文的常用方法有三种。以"咬死猎人的狗"这句话的输出结果为例:
单字方式:[咬] [死] [猎] [人] [的] [狗];
二元覆盖的方式:[咬死] [死猎] [猎人] [人的] [的狗];
分词的方式:[咬] [死] [猎人] [的] [狗]。
Lucene中负责语言处理的部分在org.apache.lucene.analysis包。其中TokenStream类用来进行基本的分词工作,Analyzer类是TokenStream的外围包装类,负责整个解析工作。有人把文本解析比喻成人体的消化过程,输入食物,分解出有用的氨基酸和葡萄糖等。Analyzer类接收的是整段文本,解析出有意义的词语。
通常不需要直接调用分词的处理类analysis,而是由Lucene内部来调用,其中:
在做索引阶段,调用addDocument(doc)时,Lucene内部使用Analyzer来处理每个需要索引的列,如图4-1所示。
引用
IndexWriter index = new IndexWriter(indexDirectory,
new CnAnalyzer(),
//用支持分词的分析器
!incremental,
IndexWriter.
MaxFieldLength.UNLIMITED);
new CnAnalyzer(),
//用支持分词的分析器
!incremental,
IndexWriter.
MaxFieldLength.UNLIMITED);
在搜索阶段,调用QueryParser.parse(queryText)来解析查询串时,QueryParser会调用Analyzer来拆分查询字符串,但是对于通配符等查询不会调用Analyzer。
引用
Analyzer analyzer = new CnAnalyzer(); //支持中文的分词
QueryParser parser = new QueryParser
(Version.LUCENE_CURRENT,"title",
analyzer);
QueryParser parser = new QueryParser
(Version.LUCENE_CURRENT,"title",
analyzer);
因为在索引和搜索阶段都调用了分词过程,索引和搜索的切分处理要尽量一致,所以分词效果改变后需要重建索引。另外,可以用个速度快的版本,用来在搜索阶段切分用户的查询词,另外用一个准确切分的慢速版本用在索引阶段的分词。
为了测试Lucene的切分效果,下面是直接调用Analysis的例子:
引用
Analyzer analyzer = new CnAnalyzer(); //创建一个中文分析器
//取得Token流
TokenStream ts = analyzer.tokenStream("myfield",new StringReader
("待切分文本"));
while (ts.incrementToken()) {//取得下一个词
System.out.println("token: "+ts));
}
//取得Token流
TokenStream ts = analyzer.tokenStream("myfield",new StringReader
("待切分文本"));
while (ts.incrementToken()) {//取得下一个词
System.out.println("token: "+ts));
}