DotLucene源码浅读笔记(1) : Lucene.Net.Analysis

本系列笔记将以DotLucene的命名空间组织行文,阅读的DotLucene版本是1.9.RC1,并且以更好的使用而非研究为目的阅读。也就是说要避难就易拉。

0, DotLucene主要命名空间概览:

命名空间

功能说明

Lucene.Net.Analysis

语言分析器,主要用于切词,支持中文主要是扩展此类

Lucene.Net.Documents

索引存储时的文档结构管理,类似关系型数据库的表结构

Lucene.Net.Index

索引管理,包括索引建立、删除等

Lucene.Net.QueryParsers

查询分析器,实现查询关键词间的运算,如与、或、非等

Lucene.Net.Search

检索管理,根据查询条件,检索得到结果

Lucene.Net.Store

数据存储管理,主要包括一些底层的I/O操作

Lucene.Net.Util

一些公用类

 

1), Lucene.Net.Analysis命名空间分析。

Lucene.Net.Analysis下,类的关系,可以看成有三个继承体系:

词法分析器(Analyzer) :词法过滤和分析的类,实际上是对分词器, 过滤器的综合包装类。

分词器(Tokenizer):对文本进行分词,可能是单字,词,二元切分等等。

过滤器(TokenFilter):对由分词器分词后的Token进行过滤,比如无意词(a ,是,的等等)或者其他的指定的需要过滤的词

下面看看每一个继承体系都有那些相关类:

 

词法分析器(Analyzer)的相关类类关系图:
 Analyzer.JPG

分词器(Tokenizer) 的相关类类关系图:
TokenFilter.JPG

过滤器(TokenFilter) 的相关类类关系图:

Tokenizer.JPG

上面的三个类关系体系里涉及到的主要类(概念)的简单说明:

类名

功能说明

Analyzer

分析器基类,词法过滤和分析的类,即把文本分解成TokenStream,即Token的序列。Analyzer只是做包装,主要还是Tokenizer在起作用

StopAnalyzer

Analyzer扩展类之一,SimpleAnalyzer功能基础上加上过滤词功能

StandardAnalyzer

Analyzer扩展类之一,也是最常用的分析器,支持中文,日文等,单字切分。

SimpleAnalyzer

Analyzer扩展类之一,将除去字符之外的符号全部过滤掉,并且将所有的字符小写(大写)化

Token

DotLucene最基本的单位,以单字切分则每个单字为一个Token,如果以中文分词来切分则每个词为一个Token

TokenStream

Token的序列

Tokenizer

继承于TokenStream,用于分词。一般扩展的自定义的分词都应该继承这个类

 

 

StandardTokenizer

Tokenizer扩展类之一,也是最常用的,支持中文,基于单字切分

TokenFilter

继承于TokenStream的子类,用于过滤。一般拓展的自定义的过滤类都应该继承该类

StandardFilter

TokenFilter拓展类之一,过滤英文字符的复数和dot(.)号.

LowerCaseFilter

对所有英文小写化

StopFilter

过滤掉指定的过滤词

 

在所有上面这个类之中,我们经常用的也是所有Analyzer中最复杂的就是StandardAnalyzer(本身不复杂,其调用的分词器复杂),下面对这个类做一个简单的分析:
StandardAnalyzer最核心,最主要的方法:

         public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader)

         {

              TokenStream result = new StandardTokenizer(reader);

              result = new StandardFilter(result);

              result = new LowerCaseFilter(result);

              result = new StopFilter(result, stopSet);

              return result;

         }

就是调用StandardTokenizer分词器对文本分词。然后调用三个过滤器(作用表格有写),其中的StandardTokenizer类及相关的类比较复杂,目前还没有完全理解。所以下面的文字是需要用批判眼光来阅读的。说白了,我是一边猜,一边看源码。以求的最准确的理解。

先做个简单的测试,通过结果来分析:

string sTemp = "我们是中国人,We are chinese";

            Analyzer analyzer = new StandardAnalyzer() ;

            StringReader sr = new StringReader(sTemp);

            TokenStream ts = analyzer.TokenStream(sr);

            Lucene.Net.Analysis.Token token = null;

            while ((token = ts.Next()) != null)

            {

                this.txtResult.Text += token.ToString();

            }

txtResult是Winform的TextBox,输出结果如下:

(,0,1,type=<CJ>)(,1,2,type=<CJ>)(,2,3,type=<CJ>)(,3,4,type=<CJ>)(,4,5,type=<CJ>)(,5,6,type=<CJ>)(we,7,9,type=<ALPHANUM>)(chinese,14,21,type=<ALPHANUM>)

 

(,0,1,type=<CJ>)来分析,因为是单字切分,所以分解成了一个一个的字。其中0,1表示这个字在文本中StartOffset,EndOffset,最后的type表示文字的类型是英文,数字,还是是中文等等。在rc1.9中支持的type可以在Lucene.Net.Analysis.Standard下的StandardTokenizerConstants类看到。而CJ代表的是中文和日文的集合。不仅仅代表中文哦。

分析到这里,我有一个疑问。DotLucene是怎么区别不同的文字的呢?那就是根据unicode编码的范围区别不同的文字。不过这句话,是我猜出来,但我始终没能在DotLucene源码中找到能支持我这句话的原代码。所以猜测始终还是猜测。鉴于本次阅读DotLucene的目的是为了更好的使用,而非研究,所以对Lucene.Net.Analysis命名空间的分析只能就此打住。

 

后记:

据我所知,现在已经有很多种第三方的Analyzer。SourceForce上的有一个ChineseAnalyzer,基于二元分词算法实现中文分词。还有基于词库实现中文分词的Analyzer,一般认为。使用针对中文优化过的Analyzer可以提高搜索准确度,但是对于大多数的搜索应用,StandardAnalyzer 绝对够用,好用。为什么呢?打个比方,拿国际经济四个字来说,如果是StandardAnalyzer的话,无论搜索 国际,经济,还是国际经济都能搜索到。但是如果用中文分词,那就难说。那就看你的中文分词怎么分 国际经济(二元分词算法的Analyzer不需要考虑这个问题)。我在给CS做的搜索系统,也是用StandardAnalyzer,绝对不用其他的Analyzer。以上纯属个人拙见。

posted @ 2006-06-25 21:41 kwklover 阅读(6746) 评论(14)  编辑 收藏 网摘 所属分类: DotLucene

  回复  引用  查看    
#1楼2006-06-25 22:25 | idior      
Analyzer这部分是Decorator模式的良好教材。可惜我当时没有写下去 :p
http://idior.cnblogs.com/archive/2006/04/27/124373.html

  回复  引用    
#2楼2006-06-25 22:37 | ww往往外[未注册用户]
牛人!!
  回复  引用  查看    
#3楼[楼主]2006-06-25 22:52 | kwklover      
@idior
你的系列文章,我都拜读过,我就是从你的系列文章开始接触DotLucene的.非常感谢.

DotLucene的整个设计架构也是很不错的.

  回复  引用  查看    
#4楼2006-06-26 09:48 | 我学习故我在      
不错,最好能在自定义Analyzer上分析下
  回复  引用    
#5楼2006-06-26 09:55 | 张老三[未注册用户]
不错,我也一直在学习lucene, 期待后续文章,
关于字符的划分,可以参考一下java.lang.Character.UnicodeBlock类,它里面定义一些字符集对应unicode编码.

  回复  引用  查看    
#6楼2006-06-26 13:37 | 蛙蛙池塘      
老三说的好像是java的lucence
  回复  引用    
#7楼2006-07-09 20:24 | 有源代码?[未注册用户]
join to qq group 1259803
  回复  引用  查看    
#8楼2007-01-01 18:11 | 随风流月      
识别字符的语言种类在
StandardTokenizerTokenManager.cs

——虽然我只有初一,但是还是掉进了编程这个坑中。

  回复  引用    
#9楼2007-02-07 00:14 | yinpingsep[未注册用户]
如果用standardanalyzer,查询应该没有问题,但是highlight好像有问题。比如我查询“中国”这个词,highlight里面还是按照“中”和“国”进行高亮,所以有时候就会高亮单独的字
  回复  引用    
#10楼2007-03-21 08:50 | 路过[未注册用户]
不知所为!
不错
  回复  引用  查看    
#12楼2009-03-27 10:33 | 风之旖旎      
看了博主的文章,明白多了



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 435421




相关文章:

相关链接: