LuceneInAction(第2版)学习笔记——第四章 Lucene的分析过程

 分析Analysis,在Lucene中指的是将域(Field)文本转换成最基本的索引表示单元————项(term)的过程。
 在搜索过程中,这些项用于决定什么样的文档能够匹配查询条件。

 分析器对分析操作进行了封装,它通过执行若干操作,将文本转换成语汇单元。
 这些操作有:
  提取单词、去除标点符号、去掉字母上的音调符号、
  将字母转换成小写(也称规范化)、去除常用词、
  将单词还原为词干形式(词干还原)、将单词转换成基本形式(词形归并lemmatization)。


 分析器的处理过程,也称为【语汇单元化过程】————tokenization。
 通过【语汇单元化过程】,从文本流中提取文本块,这些文本块称为 【语汇单元token】。

 
 在建立索引时,通过分析过程得到的【语汇单元token】就是被索引的项。
 最重要的是,只有被索引的项才能被搜索到。(除非该域没有进行分析,则整个域值都被作为一个语汇单元。)

 【语汇单元token】与它的【域名】结合合,就形成了【项term】。

 【项term】= 【域名】 + 【语汇单元token】


 使用Lucene时,选择一个合适的分析器是非常关键的。
 对分析器的选择没有唯一标准,待分析的语种是影响选择的因素之一。
 影响选择的另一因素是被分析的文本所属的领域,不同的行业有不同的术语、缩写词和缩略语。
 注意:不存在能适用于所有情况的分析器。

 

 【分析器Analyzer】 = 【分词器Tokenizer】+【N个过滤器Filter】

通常情况下,过滤器的工作比切词器简单,过滤器拿着每个token,决定是继续流转下去或者替换或者抛弃。

链上的每个过滤器按顺序执行,因此注明过滤器的顺序显得很重要。通常情况下,先执行普通过滤器,然后执行专业过滤器。

 

 

1. 使用分析器


1.1. 分析器说明


 1) 什么时候要用分析器


  分析操作会出现在任何需要将文本转换成项的时候。
  对于Lucene核心来说,分析操作会出现在两个时间点:
   建立索引期间和使用QueryParser对象进行搜索时。
  此外,如果搜索结果要高亮显示被搜索内容,也可能要用于分析操作。
  当然,高亮显示功能要调用Lucene的两个软件捐赠模块。

 

 2) 分析结果中的语汇单元取决于对应的分析器


  不同的分析器分析同样的域值,得到的语汇单元可能是不一样的。


 3) 四个常用分析器说明


  A. WhitespaceAnalyzer


   通过空格来分割文本信息,不做其它规范化处理。


  B. SimpleAnalyzer


   通过非字母字符来分割文本信息,然后将语汇单元统一为小写形式。
   注意,它会去掉数字类型的字符,但会保留其它字符。


  C. StopAnalyzer


   与SimpleAnalyzer类似,区别在于StopAnalyzer会去掉常用单词。
   默认会去掉常用单词(the a等),但也可以自己设置常用单词。


  D. StandardAnalyzer       

 
   是Lucene最复杂的核心分析器。
   它包含大量的逻辑操作来识别某些种类的语汇单元,如公司名称、Email地址、主机名称等。
   它还会将语汇单元转换成小写形式,并去除停用词和标点符号。

 Lucene的分析结果对于搜索用户来说是不可见的。
 从原始文本中提取的项会被立即编入索引,并且在搜索时用于匹配对应文档。
 当使用QueryParser进行搜索时,Lucene会再次进行分析操作,
 这次分析的内容是用户输入的查询语句的文本信息,这样就能确保最佳匹配效果。

 

1.2. 索引过程中的分析


 在索引期间,文档域值所包含的文本信息需要被转换成语汇单元。

 程序首先要实例化一个Analyzer对象,然后将之传递给IndexWriter对象。
  Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
  IndexWriter writer = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);

 如果某个域不被分析,则该域值被整个索引成一个单独的语汇单元。
 在用IndexWriter实例索引文档时,一般通过默认的分析器来分析文档中的每个域。
 如某个文档需要用特殊分析器处理的话,可以针对这个文档指定分析器:
  IndexWriter的addDocument()和updateDocument()都允许为某个文档选择对应的分析器。

 Field.Index.ANALYZED和Field.Index.ANALYXED_NO_NORMS两个参数,保证该域会被分析。
 Field.NOT_Index.ANALYZED和Field.Index.NOT_ANALYXED_NO_NORMS两个参数,保证该域不会被分析,
  而是将该域值作为一个语汇单元处理。


 
1.3. QueryParser分析


 QueryParser能很好地为搜索用户提供形式自由的查询。
 为完成这个任务,QueryParser使用分析器将文本信息分割成各个项用于搜索。

 在实例化QueryParser对象时,同样需要传入一个分析器对象:
  QueryParser parser = new QueryParser(Version.LUCENE_30, "contents", analyzer);
  Query query = parser.parse(expression);
 
 分析器会接收表达式中连续的独立的文本片段,但不会接收整个表达式。
 这个表达式可能包含操作符、圆括号或其它表示范围、通配符以及模糊查询在内的特殊表达式语法。

 查询时,QueryParser所使用的分析器必须和索引期间使用的分析器相同吗?
 不一定。

 

1.4. 解析 VS 分析 : 分析器何时不再适用


 在Lucene内部,分析器用于将域的文本内容单元化,这是分析器的一个重点任务。
 分析器可以用于每次分析一个特定的域,并且将该域内容分解为语汇单元,但是在分析器内不可以创建新的域。

 分析器不能用于从文档中分离和提取域,因为分析器的职责范围只是每次处理一个域。
 为了对域进行分离,要在分析之前预先解析这些文档。

 【解析】: 从文档中分离和提取域,可能会产生多个域
 【分析】: 每次分析一个特定的域,并且将该域内容分解为语汇单元,在分析器内不可以创建新的域

 

2. 剖析分析器


2.1. 分析器的工作原理


 (1) Analyzer类


  Analyzer类是一个抽象类,是所有分析器的基类。
  它通过TokenStream类,以一种很好的方式将文本逐字转换为语汇单元流。

  分析器实现TokenStream对象的唯一声明方法是:
  public TokenStream tokenStream(String fieldName, Reader reader)
  返回的TokenStream对象,就用来递归处理所有的语汇单元。

 

 (2) SimpleAnalyzer类


  SimpleAnalyz

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值