Lucene(发音为 ['lusen] )是一个非常优秀的开源的全文搜索引擎,我们可以在它的上面开发出各种全文搜索的应用来。Lucene在国外有很高的知名度,现在已经是Apache的顶级项目,在国内,Lucene的应用也越来越多。

 0)设有两篇文章1和2 
   文章1的内容为:Tom lives in Guangzhou,I live in Guangzhou too. 
   文章2的内容为:He once lived in Shanghai.

 2) 倒排索引:有了关键词后,我们就可以建立倒排索引了。上面的对应关系是:“文章号”对“文章中所有关键词”。倒排索引把这个关系倒过来,变成:“关键词”对“拥有该关键词的所有文章号”。文章1,2经过倒排后变成 
关键词 文章号 
  guangzhou 1 
  he 2 
  i 1 
  live 1,2 
  shanghai 2 
  tom 1

 

 关键词 文章号 [出现频率] 出现位置 guangzhou 1 [2] 3,6 he 2 [1] 1 i 1 [1] 4 live 1 [2] 2,5
 2 [1] 2 shanghai 2 [1] 3 tom 1 [1] 1

 

 

 

 

  以live 这行为例我们说明一下该结构:live在文章1中出现了2次,文章2中出现了一次,它的出现位置为“2,5,2”这表示什么呢?我们需要结合文章号和出现频率来分析,文章1中出现了2次,那么“2,5”就表示live在文章1中出现的两个位置,文章2中出现了一次,剩下的“2”就表示live是文章2中第 2个关键字。 
  以上就是lucene索引结构中最核心的部分。我们注意到关键字是按字符顺序排列的(lucene没有使用B树结构),因此lucene可以用二元搜索算法快速定位关键词。 
  实现时 lucene将上面三列(文章号和出现频率合为一列,组成频率文件)分别作为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不仅保存有每个关键词,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。

全文检索框架的实现机制:

 

全文检索 ≠ like "%keyword%"

  所以建立一个高效检索系统的关键是建立一个类似于科技索引一样的反向索引机制,将数据源(比如多篇文章)排序顺序存储的同时,有另外一个排好序的关键词列表,用于存储关键词==>文章映射关系,利用这样的映射关系索引:[关键词==>出现关键词的文章编号,出现次数(甚至包括位置:起始偏移量,结束偏移量),出现频率],检索过程就是把模糊查询变成多个可以利用索引的精确查询的逻辑组合的过程。从而大大提高了多关键词查询的效率,所以,全文检索问题归结到最后是一个排序问题。

 

  大部分的搜索(数据库)引擎都是用B树结构来维护索引,索引的更新会导致大量的IO操作,Lucene在实现中,对此稍微有所改进:不是维护一个索引文件,而是在扩展索引的时候不断创建新的索引文件,然后定期的把这些新的小索引文件合并到原先的大索引中(针对不同的更新策略,批次的大小可以调整),这样在不影响检索的效率的前提下,提高了索引的效率。
   Lucene  其他开源全文检索系统
 增量索引和批量索引  可以进行增量的索引(Append),可以对于大量数据进行批量索引,并且接口设计用于优化批量索引和小批量的增量索引。  很多系统只支持批量的索引,有时数据源有一点增加也需要重建索引。
 数据源  Lucene没有定义具体的数据源,而是一个文档的结构,因此可以非常灵活的适应各种应用(只要前端有合适的转换器把数据源转换成相应结构)。  很多系统只针对网页,缺乏其他格式文档的灵活性。
 索引内容抓取  Lucene的文档是由多个字段组成的,甚至可以控制那些字段需要进行索引,那些字段不需要索引,近一步索引的字段也分为需要分词和不需要分词的类型:
   需要进行分词的索引,比如:标题,文章内容字段
   不需要进行分词的索引,比如:作者/日期字段
 缺乏通用性,往往将文档整个索引了
 语言分析  通过语言分析器的不同扩展实现:
可以过滤掉不需要的词:an the of 等,
西文语法分析:将jumps jumped jumper都归结成jump进行索引/检索
非英文支持:对亚洲语言,阿拉伯语言的索引支持
 缺乏通用接口实现
 查询分析  通过查询分析接口的实现,可以定制自己的查询语法规则:
比如: 多个关键词之间的 + - and or关系等
 功能较强大
 并发访问  能够支持多用户的使用  功能较强大


 自动切分 词表切分 实现 实现非常简单 实现复杂 查询 增加了查询分析的复杂程度 适于实现比较复杂的查询语法规则 存储效率 索引冗余大,索引几乎和原文一样大 索引效率高,为原文大小的30%左右 维护成本 无词表维护成本 词表维护成本非常高:中日韩等语言需要分别维护。
还需要包括词频统计等内容 适用领域 嵌入式系统:运行环境资源有限
分布式系统:无词表同步问题
多语言环境:无词表维护成本 对查询和存储效率要求高的专业搜索引擎

 org.apache.Lucene.search/ 搜索入口 org.apache.Lucene.index/ 索引入口 org.apache.Lucene.analysis/ 语言分析器 org.apache.Lucene.queryParser/查询分析器 org.apache.Lucene.document/ 存储结构 org.apache.Lucene.store/  底层IO/存储结构 org.apache.Lucene.util/ 一些公用的数据结构


这些优点都是非常值得在以后的开发中学习借鉴的。作为一个通用工具包,Lunece的确给予了需要将全文检索功能嵌入到应用中的开发者很多的便利。
  此外,通过对Lucene的学习和使用,我也更深刻地理解了为什么很多数据库优化设计中要求,比如:

  1. 尽可能对字段进行索引来提高查询速度,但过多的索引会对数据库表的更新操作变慢,而对结果过多的排序条件,实际上往往也是性能的杀手之一。
  2. 很多商业数据库对大批量的数据插入操作会提供一些优化参数,这个作用和索引器的merge_factor的作用是类似的。
  3. 20%/80%原则:查的结果多并不等于质量好,尤其对于返回结果集很大,如何优化这头几十条结果的质量往往才是最重要的。
  4. 尽可能让应用从数据库中获得比较小的结果集,因为即使对于大型数据库,对结果集的随机访问也是一个非常消耗资源的操作。