Lucene3.0的主要变化

一、概述

Lucene3.0(以下简称3.0)已于2009-11-25发布,3.0版本是重大的版本,改动很大。在API上 做了很多的调整,已经删除了很多之前废弃的方法以及类,并支持了很多Java5 的新特性:包括泛型、可变参数、枚举和autoboxing等。

因此,此版本和2.x版本不能兼容,如要使用3.0版本,最好是在新项目中去使用,而不是去升级2.x或之前的版本!

二、2.9版本介绍

 

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

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

2、重开搜索

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

3、数字处理

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

4、其他优化

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

三、2.9版本和3.0比较

虽然2.9是为3.0做准备的一个版本,但是3.0和2.9相比较,变化还是比较大的,这处要体现在:

 

  1. 1、3.0抛弃了在2.9声明废弃的方法,因此3.0无法向下兼容;
  2. 2、3.0放弃了对Java1.4的支持,改为对高版本Java1.5和ant 1.7.0支持;
  3. 3、其他内核的一些变化,如oalLock.isLocked()现在会抛出IOException异常,对于一些静态变量的改变等。

四、3.0主要方法的改变

这里这种讲下目前新版本后使用建立索引以及搜索的不同。

1、建立索引

新版本在建立索引时抛弃了很多未用的方法,见下图,所有声明被抛弃的IndexWriter构造函数都在3.0中被删 除。Lucene3.0的主要变化_第1张图片

3.0版本的IndexWriter构造函数:

Lucene3.0的主要变化_第2张图片

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

2、查询

删除了Hits类,增加了TopScoreDocCollector去取得“Hits”,实际上在3.0给了个新命 名:collector。使用方式和hits类同,同时删除了Search以及QueryParser的几个构造方法,QueryParser删除了 QueryParser(String f, Analyzer a)构造方法。
新查询例子如下(蓝色部分是与以往不同的部分):[CODE=java]
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() + ” “);
}

[/CODE]

3.0版本的Search构造方法:

Lucene3.0的主要变化_第3张图片

3.0前的构造方法:

Lucene3.0的主要变化_第4张图片

五、3.0总体图

3.0版本的结构和之前的版本(2.9之前)相比,在程序结构上表现出来就只是多了一个message包,用来专门处 理国际化。 Lucene3.0的主要变化_第5张图片

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

 

你可能感兴趣的:(数据结构,框架,ant,项目管理,Lucene)