全文索引(三)lucene 分词 Analyzer
分词: 将reader通过阅读对象Analyzer字处理,得到TokenStream处理流程被称为分割。
该解释可能是太晦涩。查看示例,这个东西是什么感性的认识。
样品:一段文本“this is jack’s house”,经过分词器处理之后得到可能为jack 、house。
这个过程中:this is 称之为停留词。这种词是不会被存入索引文件的。这个主要通过StopAnalyzer分词器来实现,后面我们会讲。
jack’s 被转换为 jack 。诸如此类coming会被转换为come。全部的形式都会被最为原始的状态。
分词的过程主要由Analyzer类解析实现,而Analyzer通过调用TokenStream及其两个子类TokenFilter、Tokenizer来实现。
总体的结构类图例如以下
一. Analyzer
经常使用的有:
SimpleAnalyzer: 将查询语句转换为语素单元时完毕转换为小写的操作。
StandardAnalyzer :最为经常使用的智能分词器,通过这两个LowerCaseFilter和StopFilterTokenStream。能完毕诸如邮件、字母分析处理。
WhitespaceAnalyzer :以空格为分词符进行分析处理。
如:I am coder—-
Lucene3.5 有9种分词器。继承Analyzer抽象类内部通过tokenStream(String fieldName, Reader reader)方法来处理读取的查询数据,Analyzer和不同子类分词器的实现。应该能看到组合模式的设计。
二. TokenStream
经过分词、过滤处理后的结果流。
主要通过public abstract boolean incrementToken() throws IOException 方法来实现分词后各语素的处理读取操作。
tokenFilter 和 Tokenizer两个子类来实现 去停留词和得到分词单元。
#三. 分词一般处理流程#
分词器主要流程
- 第一步:reader对象读取分词数据
- 第二步:Tokenier 负责将一组数组分解为一个个的单元
如:I am coder—- - 第三步:经过多重过滤器对分词数据进行过滤操作。
过滤的作用是去除停留词,并形态还原,统一大写和小写等。
去除停留词: 就是去除相似in of this 等没有确切含义的词。这些不会被当做分词单元。形态还原则是将过去分词、过去式这种词还原为原来的形态。如:termming-term。
demo
public void createToken(String strContent,Analyzer analyer){
try {
//1.创建TokenStream对象
TokenStream tokenStream=analyer.tokenStream("", new StringReader(strContent));
//charTermAttribute 保存了分词中的各个语素单元
CharTermAttribute cta=tokenStream.addAttribute(CharTermAttribute.class);
//PositionIncrementAttribute 保存分词各个语素单元的位置信息
PositionIncrementAttribute pta=tokenStream.addAttribute(PositionIncrementAttribute.class);
//OffsetAttribute 保存各语素单元的偏移量
OffsetAttribute oab=tokenStream.addAttribute(OffsetAttribute.class);
//读取分词单元的信息
while(tokenStream.incrementToken()){
System.out.println("----------cta---------="+cta);
System.out.println("----------pta---------="+pta);
System.out.println("----------oab---------="+oab);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private LuceneAnalyzerUtil luceneAnalyzer=null;
public testAnalyzer(){
luceneAnalyzer=new LuceneAnalyzerUtil();
}
@Test
public void testCreateToken(){
//标准分词器。作为一般标准的分词器有自己智能的一面,
Analyzer analyzer1=new StandardAnalyzer(Version.LUCENE_35);
Analyzer analyzer2=new StopAnalyzer(Version.LUCENE_35);
Analyzer analyzer3=new ClassicAnalyzer(Version.LUCENE_35);
Analyzer analyzer4=new KeywordAnalyzer();
Analyzer analyzer5=new WhitespaceAnalyzer(Version.LUCENE_35);
luceneAnalyzer.createToken("I am human,I am special", analyzer1);
luceneAnalyzer.createToken("I am human,I am special", analyzer2);
luceneAnalyzer.createToken("I am human,I am special", analyzer3);
luceneAnalyzer.createToken("I am human,I am special", analyzer4);
luceneAnalyzer.createToken("I am human,I am special", analyzer5);
}
总的来讲,lucene的分词器主要做了一个什么样的工作呢?从查询语句分解为一个个查询单元的工作。
这么做的目的是为了lucene在查询时候更好的细粒度的去匹配已创建的索引文件。