lucene4.5源码分析系列:lucene概述

来源:互联网 发布:淘宝banner制作 编辑:程序博客网 时间:2024/05/16 06:01

  lucene概念

  lucene被定义为开源的全文检索引擎包。其主要功能就是提供索引和搜索两大模块的API。

  关于lucene的整个架构(图是借用的)

  下面这个架构图其实揭示的就是lucene的两大基础:索引和搜索

  下面这个图其实说的是lucene的几大模块(其实也就是几大流程):分析,索引,查询解析,检索,相关性分析

  

  个人认为要深入理解lucene,首先得理解两个大的基础,一是索引的基础,即索引文件格式(当然还包括索引的);二是搜索的基础,即搜索算法评分原则。接下来的文章首先会讲这两点,虽然比较枯燥,但是个人认为对于理解索引和搜索有相当重要的作用。

  本文使用最新的lucene4.5版本。关于现在网上大量之前的版本,我也会尽量说明之前版本的问题,以及4.5如何使用替代方案的。

  既然是概述,我们先来回顾一下lucene发展至今的一些能力

  1. 索引和搜索能力。从lucene的各个版本的更新历史来看,lucene的索引和搜索速度从1.0到现在有了多次的提升,比如1.4.1,2.2,2.3,2.4,内存和磁盘占用更小。

  官方的数据是:在现代的计算机上索引速度可以到150G/小时,并且只需要1M内存(这个还得看怎么用的吧),由于使用了压缩技术,索引大小仅为文本的20%到30%

  2. 多种索引存放方式,增量索引,近实时搜索。增量索引使得索引在第一次建好之后需要维护索引时可以基于第一次的基础维护,而不是每次都只能重建,增量索引可以大大的减少维护成本。近实时搜索是lucene2.9引入的一项重要功能,即文档的即时索引和即时搜索。在2.9以前,建立索引到提交(commit)索引之间有可能会有很长时间的间隔,这段间隔的内容是无法被索引到的,而2.9以后能够在查询的时候实时刷新缓冲区中新增或者删除的文档。

  3. 过滤,排序,高亮,丰富的查询类型可以处理各种查询case。排序是实际业务中一项重要的能力,1.4以后开始提供这项能力,默认情况下,lucene通过关联性评分对匹配文档进行降序排序,关联性最好的在最前面,但是可以根据需要来定制类似淘宝的商品排序能力。另外,lucene提供phrase queries, wildcard queries, proximity queries, range queries等等来处理各种查询的情况。

  4. 跨度查询等技术。跨度查询提供的是位置感知能力。比如一段文本中单查询奥巴马和叙利亚,可能查到的是奥巴马演讲,叙利亚局势,是两个不相干的信息。但是如果查询所有靠近奥巴马并且包含叙利亚的文本,可能查出来的就是奥巴马向叙利亚宣战。这个能力可以让我们的查询更加精确。

  5. 灵活的评分机制。4.0以前,评分算法都是空间向量模型,难于扩展,而且没有统计到Field。4.0以后,增加了灵活的评分机制,可以支持各种类型的评分模型,比如,基于概率的BM-25,语言模型,随机分歧,基于信息量的模型。根据不同的需要可以定制。

  6. 利用codec解耦lucene的索引与架构。解耦的好处不言而喻,可以让lucene支持更多的索引,使得适用范围变大,适应未来的需要,同时也可以自定义索引格式。

  可以看出来,以上两个方式都是用类似插件的机制来提高灵活性。

  7. 多线程并发创建索引。 4.0以前,虽然可以做到多个线程建索引,但是当索引需要写回硬盘时则需要一个一个顺序flush,而4.0以后,已经可以做到并发写回了。


  8. 基于有限自动机的模糊匹配算法(FSA算法)

  如图,fst匹配了mopmothpopstarstop和top,对于模糊搜索而言,FST就相当于一个SortedMap,但是相对而言,FST占用更少内存,而sortedMap则是重复存了这些字母,而FST的cpu花销相对较大。对于lucene而言,内存利用甚至超过了CPU,因而采用FST是一个比较明智的选择。更多内容请参考文末文档。


索引和搜索组件

  接下来简单介绍一下lucene的索引和搜索组件,以便在后面的讲解中有基础的认识

  

  索引

  Field:域是lucene索引中最细粒度的单位,lucene的对象非常形象化,一篇现实的文档可能会分许多个部分,比如:标题,作者,内容,都是不同的域,如果用数据库打比方,那么Field就是列。

  Document:文档是加入索引的单位,一篇文档由多个域组成,可以把Document理解为一篇虚拟的文档,用数据库来类比,一个Document就是一条记录。

  Directory:Directory是抽象的索引存放位置,有许多子类实现,比如,FSDirectory是最常用的索引放入磁盘,RAMDirectory将索引放到内存,FileSwitchDirectory则是根据文件扩展名在两个文件目录之间切换(试验阶段)等。其中FSDirectory.open会根据不同的平台返回它的不同子类,典型的是solaris和window64-bit会返回MMapDirectory,非window会返回NIOFSDirectory,在windows 32-bit则会使用SimpleDirectory。

  Analyzer:分析器的主要作用是从文本中提取出待使用的语汇单元,并且处理一些无用的信息。提取语汇单元的过程还包括一些额外的处理,比如丢掉停用词(stop words),或者把这些语汇变成小写从而在其后的搜索中做到忽略大小写,又或者从一个单词提取出词干,比如drove,driven在被处理为drive这样搜索drive时就能够同时搜索到这些变化后的词,当然,还有一个比较重要的作用,就是我们的中文分词。而且分析器不仅在索引过程中会用到,同时还会在搜索过程,可以想象,索引过程要将文档提取出语汇单元并索引,而搜索过程又要将待搜索查询分解为语汇单元。所以,分析器非常重要,甚至关系到了搜索质量的好坏。

  IndexWriter:IndexWriter是整个索引过程最为重要的角色和入口,它的许多方法都非常值得推敲和斟酌。通过它,可以将索引事实上写入磁盘。由于它如此重要,在后面会专门撰文对其进行分析。现在你只要知道,如果索引是一个数据库,那么IndexWriter就是对索引进行增删查改的最核心组件了。

  

  搜索

  IndexReader:IndexReader是一个相对比较“重”的类,之所以这么说,是因为IndexReader负责打开索引,提供底层API等工作,这些工作相对耗时,所以无论是多线程调优还是各种建议都号召尽量复用IndexReader,减少不必要的性能损失。

  QueryParser:QueryParser被用来解析用户输入的查询表达式,lucene经过这么久的进化,已经有一套类似google的查询表达式语言,QueryParser就是负责解析这套语言的。上图中QueryParser将用户输入的查询表达式解析过后,将中间的待查找文本送到Analyzer并得到语汇结果,最后将结果包装成查询对象并送往IndexSearcher。

  Query:Query就是QueryParser解析过后的结果对象,如果不通过QueryParser来解析得到Query,则可以自己选择使用各种多样化的Query子类,比如BooleanQuery, PrefixQuery, NumericRangeQuery, SpanQuery等等。

  IndexSearcher:IndexSearcher是与IndexWriter遥相呼应的一个重要的类,方法非常精炼实用,为我们查询提供了可能会用到的API。IndexSearcher的实际工作过程非常“简单”,从上图也可以看出来,它有两方面的输入,一边是索引词库,一边是查询对象。通过一系列的评分算法计算之后,查找索引库中与待查对象关联度较高的文档。如果不仔细考虑,可能会奇怪为什么需要评分算法,实际上,查询结果中大多数都包含相同的待查询关键字,因此很难比较都包含待查关键字的N篇文档从而得出查询结果的排列位置,再加上待查询的基数过于巨大,使得查询结果的排列变得非常重要,越靠前的位置越发珍贵。靠后的结果评分往往较低,并且查找效率不高,所以许多搜索引擎都不提供深度搜索,比如google就不提供查询数量在1000以后的结果。究其原因,其实就是求topK与排序的区别,在结果集数量就较高的情况下(假设为1000000),极端情况下,前1000个结果(即top1000)与top1000000(即整个排序)是有巨大差别的,topK比较好的时间复杂度可以到NlogK,而排序的时间复杂度是NlogN,由于K往往只是N中很小一部分,所以差异是比较显著的。在lucene中,分页的查询速度就可以明显看出来区别。一般靠前的页面查询较快,靠后的查询较慢。

  TopDocs:TopDocs是一个前N个搜索结果的集合,每个结果用一个docId来标识,TopDocs可以得到几个重要的查询结果,比如,总的查询数量,查询结果对象数组以及最大评分。

  最后,关于本系列文章的组织:

  首先是lucene的概述,然后是2个基本问题,即索引的文件格式及搜索的评分算法,他们分别是索引和搜索的基础,接下来主要是3个模块的流程及一些宏观描述,这三个大模块分别是,索引部分,搜索部分以及分析器部分,最后来讨论之前没有提及但又比较重要的细节问题,主要是微观部分

  另外,本系列参考了一些文章,比较好的有两份重点推荐:一份是觉先牛人写的lucene原理:http://www.cnblogs.com/forfuture1978/archive/2010/06/13/1757479.html,对于该博文,只能表示膜拜,因为分析得及其透彻和细致,这需要花大量的时间;另一份是annotated lucene,也是不可多得的参考资料。再此不得不感谢这些牛人的贡献,当然,这两份文档都是基于lucene3来写的,与lucene4有一定的差别,但是索引过程,评分公式和搜素这些部分大体是没变的,因此也可以看出他的经典

  下面是文章的索引,有很多部分暂时还没有完成,将会在后面一一补完,尽请见谅。

  lucene4.5源码分析系列:lucene默认索引的文件格式-总述

  lucene4.5源码分析系列:lucene索引的文件格式1,2,3,4

  lucene4.5源码分析系列:lucene的默认评分算法-向量空间模型(Vector Space Model)

  lucene4.5源码分析系列:索引的创建过程

  lucene4.5源码分析系列:搜索过程

  lucene4.5源码分析系列:分析器

  lucene4.5源码分析系列:索引缓存以及刷新

  lucene4.5源码分析系列:事务

  lucene4.5源码分析系列:搜索缓存

  lucene4.5源码分析系列:优化


  lucene简介:http://www.chedong.com/tech/lucene.html

  lucene入门系列:http://blog.csdn.net/column/details/jadyerlucene.html

  lucene4新特性:http://files.meetup.com/1446074/ImprovedSearchWithLucene4.pdf 

                                 http://blog.csdn.net/accesine960/article/details/8066877

  lucene4重大升级:http://blog.csdn.net/accesine960/article/details/6780068

  lucene4 changing bit:blog.mikemccandless.com/2012/07/lucene-400-alpha-at-long-last.html

  lucene4:http://doc.okbase.net/qindongliang1922/archive/16465.html

  lucene4.3与3.5性能对比:http://www.cnblogs.com/seanvon/p/3173734.html

  lucene4性能调优:http://archive.apachecon.com/eu2012/presentations/06-Tuesday/PR-Lucene/aceu-2012-lucene-4-performance-tuning.pdf

  lucene FST http://blog.mikemccandless.com/2010/12/using-finite-state-transducers-in.html

  FSA算法 http://www.cs.nyu.edu/~mohri/pub/fla.pdf

  lucene常用操作 http://www.wizzer.cn/?p=2299

  lucene官方资料 http://lucene.apache.org/core/4_5_0/index.html

  term vector 

http://www.iteye.com/topic/724989

  《lucene in action》

原创粉丝点击