当前位置:文档之家› lucene版本对比

lucene版本对比

lucene版本对比
lucene版本对比

一、为什么使用lucene

1、Lucene不是一个完整的全文索引应用,而是是一个用JAVA写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。这样的定位,使得lucene有很高的抽象层次,便于扩展和整合到已有的系统。因为对于大多数的全文搜索应用来说,我们需要的是一个开发工具包而不是最终产品(虽然很多搜索引擎也可以扩展特性功能)。这也是程序员最愿意接受的封装层次。

2、Lucene的API接口设计的比较通用,输入输出结构都很像数据库的表==>记录==>字段,所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。(上面语句有些来自在应用中加入全文检索功能——基于JAVA的全文索引引擎Lucene简介)。

二、lucene4.0新特性较重要部分

1、全部使用字节( utf-8 tytes )替代string来构建 term directory 。

带来的好处是:索引文件读取速度 30 倍的提升;占用原来大约10%的内存;搜索过程由于去掉了字符串的转化速度也会明显提升;

但是如果说这上面的好处只是一个副产品,你会怎么想?没错,Mysql有MyIsam,Innodb等诸多引擎供我们选择的,Lucene为什么不能向这个方向发展呢?

实现这个机制的模块叫:Codec (编码器),你可以实现自己的Codec 来进行自定义的扩展,很显然Codec的操作对象是Segment 。

2、支持多线程建索引,支持:concurrent flushing。

了解过Lucene 3.X的同学们都知道,诸如XXXPerThread 的类在建索引的时候已经支持多线程了,但是当每个线程的内存达到指定上限(maxBufferedDocs or ramMaxBufferSizeMB)的时候就需要写到硬盘上,而这个过程仍然不是多线程的,仍然需要一个个排队Flush到硬盘。Lucene 4.0 终于支持 concurrent flushing 了。DocumentsWriterPerThread ,Lucene 4.0 的Concurrent Flushing 正是这个类来实现的。

3、基于有限自动机的模糊匹配算法(FSA算法),FuzzyQuery

FuzzyQuery 这类查询估计大家用的比较少。在英文中单词拼写错误,比如: Lucene, Licene , lucen 等就可以用FuzzyQuery来进行查询提高查全率。

在lucene 4.0 之前的FuzzyQuery 的实现非常耗费cpu,实现算法也很暴力。具体过程是:读取每个term,然后计算每个term与查询词的“编辑距离”,如果在指定的范围内则返回。 Lucene 4.0 使用Levenshtein Automaton 的来衡量文字的"编辑距离" ,使用有限状态自动机来进行计算。以数百倍的效率提升了FuzzyQuery 的效率。

三、lucene4.0正式版亮点功能:

一、通过解码器Codec 机制 Lucene 索引格式与Lucene架构解耦,变成了Plugin方式实现,包括:Terms , Postings lists ,Stored 字段,Term Vectors 等都可以以自定义的格式予以支持。正如Mysql支持多种存储引擎一样,现在Lucene也可以了。

二、排序相关的算法与向量空间模型解耦(即Lucene中经典的经典的(TF/IDF)模型)。同时提供:最佳匹配 Okapi BM 25,随机分歧(Divergence from Randomness ),语言模型和基于信息量的模型。不同的算法模型可以组合串联起来使用,这等于完全解放了Lucene的生产力!。

三、新的DocValues类型可以为每个文档提供存储额外的类型数据。类似:PayLoad, 可以在用这个特性自定义排序打分参数。

四、IndexWriter 写入索引到硬盘支持完全并发,之前IndexWriter在应用层能多线程调用,但在写入硬盘的时候还是逐个线程顺序写入的。这对于经常要重建索引的场景,减少了等待索引的时间。

五、每个Document的标准化因子 norms 不再局限于一个字节。自定义排序的实现可以使用任何DocValues类型的排序因子。

六、索引结构更加透明化,增加了索引统计机制,利用这些统计信息,Lucene索引内容不再是一个黑匣子了。包括:提供针对term 或者Field的token数量,针对某个filed的Posting数量,包含某个field的positing的文档数量。当然有了这些索引统计的数据后,就可以自定义的改进评分机制了。也就是说以下方法将会成为你的新朋友:

TermsEnum.docFreq(),TermsEnum.totalTermFreq(),Fields.getUni queTermCount(),Fields.getUniqueFieldCount()

七、索引term不再局限于UTF-16的字符格式,Lucene 4.0中 term

可以是任何二进制数值(java中的byte数组)。默认情况下文本类term是UTF-8字节方式存储。

八、在搜索时使用Filter效率有大幅提升

九、针对索引merge线程添加了IO限速机制,减少搜索线程与合并索引线程引起的IO争用现象。

十、由于架构的解耦,增加了一系列可插拔和可替换的模块,包括:

A: 添加编码器codec:针对类 Hadoop DFS 的文件系统提供。

B: 内存编码器codec:把所有的term和posting放到一个内存中的FST(有限状态机),针对内存型应用提升了搜索速度。

C: 脉冲编码器codec:主要利用了 Zipf 定律,根据term的频率,把频率达到制定阈值的term以inline的方式存储。

了解c++ inline 函数的同学,应该知道inline 对于提升函数调用速度的威力吧。

D: 明文编码器codec: Lucene的索引结构为了提升效率,从来都是一个黑匣子。现在这个黑匣子可以以明文的方式存储了。很显然这个编码器主要是调试、演示用的。估计很多需要写论文的同学们很乐意使用这个功能。

E: Bloom编码器codec: 国内很多人把Bloom翻译为布隆,我还是喜欢直接用英文的Bloom。

F:直接编码器 codec : 由这个名字可以看到,这个编码器是

为提升效率用的,主要针对高内存需求类的场景定制的。

G: 块解码器 codec: 使用了一个新的索引结构和压缩模式schema。

十一、Term 偏移量可以选择与Postings list存储在一起。

十二、新增AutomatonQuery ,用来返回所有Term匹配有限状态机文章列表

十三、FuzzyQuery 查询速度提升了100-200倍。

十四、新增拼写检查器DirectSpellChecker,新的拼写检查器不需要单独的索引,能够直接使用主索引。

十五、运行中的内存数据结构优化,包括:term 目录,FiledCache 等。

以:500万wekipedia数据为例 3.x 索引时需要600M内存,4.x 索引时需要 200M内存。

十六、所有的搜索逻辑现在针对每个segment上工作。IndexReaer 也被完全重构,变成了:Atomic 和 Composite Reader。

这个变化比较大,我们知道Lucene在生成索引的时候会先生成小的Segment然后逐渐合并成大的Segment。Lucene的所有结构和组件都是以多个Segment为导向进行设计架构的。为搜索多个Segment需要MultiReader,而多Reader的会导致在搜索TermEnum 或者 Postings 的时候搜索效率的下降。因此新的Reader去掉了MultiReader,以Atomic和Composite Reader 代替。

十七、Lucene 4.0 提供了模块化的API。以模块化的方式提供

了非结构化信息管理分析器和空间信息搜索模块。

Lucene4.x与lucene3.x的不同之处

lucene3.x的时候创建Field的时候可以直接指定存储和索引的选项类下下边这样:

doc.add(newField("createrId",diaryField.getCreaterId()+"",Store.YES,I ndex.NOT_ANALYZED_NO_NORMS));

而4.x貌似去掉了索引选项,只有存储的选项,但是在4.x中我们可以直接用Lucene封装好的一些Field的子类,比如TextField,StringField,DoubleField 等

类似下边这样:

Field filePahtField

=newTextField("filePath","/home/jiaoyiping",Field.Store.YES);

doc.add(filePahtField);

或者实用FieldType,这样可以更加可配置化

FieldType fieldType = new FieldType();

fieldType.setIndexed(true);

fieldType.setStored(true);

fieldType.setDocValueType(type);

Field field22 = new

Field("fileName",f.getFileName,fieldType);

doc.add(field22);

Lucene3.x相对于lucene2.x的主要变化

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

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

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公里范围内的所有超市”)。

3.0主要方法的改变

1、建立索引

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

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构造方法:

相关主题
文本预览
相关文档 最新文档