全文搜索引擎会用某种算法对要建索引的文档进行分析, 从文档中提取出若干Token(词元), 这些算法称为Tokenizer(分词器), 这些Token会被进一步处理, 比如转成小写等, 这些处理算法被称为Token Filter(词元处理器), 被处理后的结果被称为Term(词), 文档中包含了几个这样的Term被称为Frequency(词频)。 引擎会建立Term和原文档的Inverted Index(倒排索引), 这样就能根据Term很快到找到源文档了。 文本被Tokenizer处理前可能要做一些预处理, 比如去掉里面的HTML标记, 这些处理的算法被称为Character Filter(字符过滤器), 这整个的分析算法被称为Analyzer(分析器)。
整个分析过程,如下图所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package
org.lucene.test;
import
org.apache.lucene.analysis.Analyzer;
import
org.apache.lucene.analysis.core.SimpleAnalyzer;
import
org.apache.lucene.analysis.core.StopAnalyzer;
import
org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import
org.apache.lucene.analysis.standard.StandardAnalyzer;
import
org.junit.Test;
import
org.lucene.Util.AnalyzerUtils;
public
class
TestAnalyzer {
@Test
public
void
test01()
throws
Exception {
Analyzer a1 =
new
StandardAnalyzer();
//标准分词器
Analyzer a2 =
new
StopAnalyzer();
//停用分词器
Analyzer a3 =
new
SimpleAnalyzer();
//简单分词器
Analyzer a4 =
new
WhitespaceAnalyzer();
//空格分词器
AnalyzerUtils.displayToken(txt, a1);
AnalyzerUtils.displayToken(txt, a2);
AnalyzerUtils.displayToken(txt, a3);
AnalyzerUtils.displayToken(txt, a4);
}
@Test
public
void
test02()
throws
Exception {
Analyzer a1 =
new
StandardAnalyzer();
//标准分词器
Analyzer a2 =
new
StopAnalyzer();
//停用分词器
Analyzer a3 =
new
SimpleAnalyzer();
//简单分词器
Analyzer a4 =
new
WhitespaceAnalyzer();
//空格分词器
String txt =
"我来自遥远的哈尔滨,大东北帝国冰城皇家科技学院--黑龙江科技大学"
;
//可以发现对中文支持无效,不支持中文
AnalyzerUtils.displayToken(txt, a1);
AnalyzerUtils.displayToken(txt, a2);
AnalyzerUtils.displayToken(txt, a3);
AnalyzerUtils.displayToken(txt, a4);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package
org.lucene.Util;
import
java.io.IOException;
import
java.io.StringReader;
import
org.apache.lucene.analysis.Analyzer;
import
org.apache.lucene.analysis.TokenStream;
import
org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
public
class
AnalyzerUtils {
public
static
void
displayToken(String str,Analyzer a)
throws
Exception{
TokenStream stream = a.tokenStream(
"content"
,
new
StringReader(str));
stream.reset();
//在4.0以后的版本必须先reset一次
//创建一个属性,这个属性被添加到流中,随着这个TOkenStream增加,这个属性也增加
CharTermAttribute cta = stream.addAttribute(CharTermAttribute.
class
);
while
(stream.incrementToken()) {
System.out.print(
" [ "
+cta+
" ] "
);
}
System.out.println();
}
}
|