Lucene3.0 简单解析

一、 概述
      Lucene3.0(以下简称3.0)已于2009-11-25发布,3.0版本是重大的版本,改动很大。在API上做了很多的调整,已经删除了很多之前废弃的方法以及类,并支持了很多Java5 的新特性:包括泛型、可变参数、枚举和autoboxing等。
      因此,此版本和2.x版本不能兼容,如要使用3.0版本,最好是在新项目中去使用,而不是去升级2.x或之前的版本!

二、3.0的变化

1、2.9版本介绍:

      由于新版本变动很大,官方是不推荐从旧版本升级到新版本的。因为改动会很大。
      其实在2.9版本时改动就很大,因为2.9版本就是为3.0做准备的,但是为了向下兼容,2.9并没有抛弃之前的旧方法,所以可以直接向下兼容。2.9版本主要是在性能方面的优化,包括在Lucene对Lucene底层的内部结构改进、索引的管理方式等多个方面。

1.1、索引文件改进
      Lucene的索引数据是存放在独立的文件中的,这些文件就是存储着索引数据库一些列分离的“片段”。当我们想索引中增加文档时,便会不断的创建一些可以合并的新片段,因为读写文件的开销比较大,因此这些字段信息Lucene并非每次都直接加到索引文件里面去,而是先缓存,等到一定量的时候再一次写到文件中。在2.9以后,Lucene会为每个片段分别管理FieldCache以此避开跨片段加载FieldCatch的需求,这样就解决了Lucene跨片段加载FieldCatch的效率很低下问题,这个改动大为提高了性能。Lucid Imagination的Mark Miller运行了一个简单的性能测试,表明在5,000,000个不同字符串下的情况下,Lucene 相对于2.4版本会获得15倍左右的性能提高:
Lucene 2.4: 150.726s
Lucene 2.9: 9.695s

1.2 重开搜索
      新版本引入了IndexWriter.getReader()方法,它可用于搜索目前完整的索引,包括当前IndexWriter会话中还没有提交的改变,这带来了接近于实时搜索的能力。此外,你还可以调用IndexWriter.setMergedSegmentWarmer()方法进行“预热”,这样那些片断便可以立即投入使用了。

1.3、数字处理
      2.9版本之前的版本,都是基于文本搜索的,因为对于很多数字的处理方式就很头疼,例如在我们项目中遇到的很多问题都是由于把数字当作了文本处理出现的BUG:
     1、搜索价格的5,把包含.5的也搜索出来了;
     2、排序(降序)时,把800排到5000前面;
     ……
     这些都是由于Lucene把所有的都作为文本处理的方式造成的问题。Lucene 2.9以后已经自带对数字的处理方式。Field和Query类会采取合适的精度进行索引和搜索,这样大大降低了需要搜索的关键字数量,使查询的响应能力得以显著提高。


1.4 其他优化
      引入了新的查询类型和适用性更广的多关键字查询(通配、前缀等等)方式,以及新的针对波斯语,阿拉伯语及中文的分析器。此外,这次更新还包括更好Unicode支持,一个新的查询分析框架,以及对地理位置的查询,它允许根据距离信息对文档进行过滤和排序(如“找出我家5公里范围内的所有超市”)。

2、2.9版本和3.0比较
 
虽然2.9是为3.0做准备的一个版本,但是3.0和2.9相比较,变化还是比较大的,这处要体现在:
1、3.0抛弃了在2.9声明废弃的方法,因此3.0无法向下兼容;
2、3.0放弃了对Java1.4的支持,改为对高版本Java1.5和ant 1.7.0支持;
3、其他内核的一些变化,如oalLock.isLocked()现在会抛出IOException异常,对于一些静态变量的改变等。

3、主要方法的改变
 
这里这种讲下目前新版本后使用建立索引以及搜索的不同。

3.1、建立索引
新版本在建立索引时抛弃了很多未用的方法,见下图,所有声明被抛弃的IndexWriter构造函数都在3.0中被删除。

 


3.0版本的IndexWriter构造函数:

 


在增加索引时,每个field的常量也有改变,具体如下:

3.0和之前版本的常量修改
 
3.0
 2.9
 所属类
 
ANALYZED
 TOKENIZED
 Field
 
NOT_ANALYZED
 UN_TOKENIZED
 
NOT_ANALYZED_NO_NORMS
 NO_NORMS
 
已删除
 COMPRESS
 

3.2、查询
      删除了Hits类,增加了TopScoreDocCollector去取得“Hits”,实际上在3.0给了个新命名:collector。使用方式和hits类同,同时删除了Search以及QueryParser的几个构造方法,QueryParser删除了 QueryParser(String f, Analyzer a)构造方法。
新查询例子如下(蓝色部分是与以往不同的部分):
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, field, new StandardAnalyzer(Version.LUCENE_CURRENT));  
Query query = parser.parse(q);  
TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);  
IndexSearcher is = new IndexSearcher(FSDirectory.open(file), true);  
is.search(query, collector);  
ScoreDoc[] docs = collector.topDocs().scoreDocs;  
for (int i = 0; i < docs.length; i++) {  
    Document doc = is.doc(docs[i].doc); // new method is.doc()  
    System.out.println(doc.getField(“name”) + " " + docs[i].toString() + " ");  

QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, field, new StandardAnalyzer(Version.LUCENE_CURRENT));
Query query = parser.parse(q);
TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);
IndexSearcher is = new IndexSearcher(FSDirectory.open(file), true);
is.search(query, collector);
ScoreDoc[] docs = collector.topDocs().scoreDocs;
for (int i = 0; i < docs.length; i++) {
    Document doc = is.doc(docs[i].doc); // new method is.doc()
    System.out.println(doc.getField(“name”) + " " + docs[i].toString() + " ");
}


3.0版本的Search构造方法:

 


3.0前的构造方法:

 
三、总体图
      3.0版本的结构和之前的版本(2.9之前)相比,在程序结构上表现出来就只是多了一个message包,用来专门处理国际化。


      见上图,可以看到,3.0和之前的版本一样还是由对外接口、索引核心以及基础结构封装三大部分共八个模块(也即包package),详细介绍详见附件一。
我们从上图也可以看到Lucene搜索时的调用关系:当我们要查询一个词时,在查询模块(search)会先调用语法分析器(queryParser)对查询语句进行分析,语法分析模块调用了词法分析器(analysis)进行词法分析,如对搜索关键字分词、过滤等,词法分析器在使用时会根据实际情况调用国际化模块(message)进行一些国际化的处理。当这些前置工作做完之后,才真正进入到搜索核心,首先会调用索引模块(index),它负责向底层的存储类(store)去读取索引文件里面的数据,然后返回给查询模块。其他模块在整个搜索过程中是作为公共类存在的。

附件一、 Lucnen3.0包详细介绍
 
1、analysis
      Analysis包含一些内建的分析器,例如按空白字符分词的WhitespaceAnalyzer,添加了stopwrod过滤的StopAnalyzer,最常用的是StandardAnalyzer。

2、document
      Document包含文档的数据结构,例如Document类定义了存储文档的数据结构,Field类定义了Document的一个域。

3、index
      Index包含了索引的读写类,例如对索引文件的segment进行写、合并、优化的IndexWriter类和对索引进行读取和删除操作的 IndexReader类,这里要注意的是不要被IndexReader这个名字误导,以为它是索引文件的读取类,实际上删除索引也是由它完成, IndexWriter只关心如何将索引写入一个个segment,并将它们合并优化;IndexReader则关注索引文件中各个文档的组织形式。

4、queryParser
      QueryParser包含了解析查询语句的类,lucene的查询语句和sql语句有点类似,有各种保留字,按照一定的语法可以组成各种查询。 Lucene有很多种Query类,它们都继承自Query,执行各种特殊的查询,QueryParser的作用就是解析查询语句,按顺序调用各种 Query类查找出结果。

5、search
      Search包含了从索引中搜索结果的各种类,例如刚才说的各种Query类,包括TermQuery、BooleanQuery等就在这个包里。

6、store
      Store包含了索引的存储类,例如Directory定义了索引文件的存储结构,FSDirectory为存储在文件中的索引,RAMDirectory为存储在内存中的索引,MmapDirectory为使用内存映射的索引。

7、util
      Util包含一些公共工具类,例如时间和字符串之间的转换工具。

8、message
      处理国际化的类。

附件二、Lucene相关名词解释(部分)
 
1、IndexWriter
      lucene中最重要的的类之一,它主要是用来将文档加入索引,同时控制索引过程中的一些参数使用。

2、Analyzer
      分析器,主要用于分析搜索引擎遇到的各种文本。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。

3、Directory
      索引存放的位置;lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectory和RAMDirectory两个类。

4、Document
      文档;Document相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。

5、Field
      字段。

6、IndexSearcher
      是lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具;

7、Query
      查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。

8、QueryParser
       是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liudj/archive/2010/02/03/5284149.aspx

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值