`

Lucene构架全文搜索引擎

    博客分类:
  • Java
阅读更多


Lucene 历史

    是一个基于 Java 的全文索引工具包,Lucene的贡献者 Doug Cutting 是一位资深全文索引/检索专家,曾经是 V-Twin 搜索引擎(Apple 的 Copland 操作系统的成就之一)的主要开发者,后在 Excite 担任高级系统架构设计师,目前从事于一些 Internet 底层架构的研究。他贡献出的 Lucene 的目标是为各种中小型应用程序加入全文检索功能。

    Lucene 的发展历程:早先发布在作者自己的 www.lucene.com,后来发布在 SourceForge,2001年年底成为 APACHE 基金会 Jakarta 的一个子项目。已经有很多Java项目都使用了Lucene作为其后台的全文索引引擎,比较著名的有:

Jive:WEB论坛系统;

Eyebrows:邮件列表 HTML 归档/浏览/查询系统,本文的主要参考文档“TheLucene search engine: Powerful, flexible, and free”作者就是 EyeBrows 系统的主要开发者     之一,而 EyeBrows 已经成为目前 APACHE 项目的主要邮件列表归档系统;

Cocoon:基于 XML 的 Web 发布框架,全文检索部分使用了Lucene;

Eclipse:基于 Java 的开放开发平台,帮助部分的全文索引使用了 Lucene。

Lucene优点

Lucene作为一个全文检索引擎,其具有如下突出的优点:

(1)索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。

(2)在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。

(3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能

(4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。

(5)已经默认实现了一套强大的查询引擎,用户无需自己编写代码即使系统可获得强大的查询能力,Lucene的查询实现中默认实现了布尔操作、模糊查询(Fuzzy Search)、分组查询等等。

面对已经存在的商业全文检索引擎,Lucene也具有相当的优势。首先,它的开发源代码发行 方式(遵守Apache Software License),在此基础上程序员不仅仅可以充分的利用Lucene所提供的强大功能,而且可以深入细致的学习到全文检索引擎制作技术和面相对象编程的 实践,进而在此基础上根据应用的实际情况编写出更好的更适合当前应用的全文检索引擎。在这一点上,商业软件的灵活性远远不及Lucene。其次, Lucene秉承了开放源代码一贯的架构优良的优势,设计了一个合理而极具扩充能力的面向对象架构,程序员可以在Lucene的基础上扩充各种功能,比如 扩充中文处理能力,从文本扩充到HTML、PDF[13]等等文本格式的处理,编写这些扩展的功能不仅仅不复杂,而且由于Lucene恰当合理的对系统设 备做了程序上的抽象,扩展的功能也能轻易的达到跨平台的能力。最后,转移到apache软件基金会后,借助于apache软件基金会的网络平台,程序员可 以方便的和开发者、其它程序员交流,促成资源的共享,甚至直接获得已经编写完备的扩充功能。

   后来有移植到各种平台和语言的版本。Ruby, .net平台的Lucene.net, PHP里的Zend框架也集成Lucene全文搜索引擎。

Lucene建立索引

    为了对文档进行索引,Lucene 提供了五个基础的类,他们分别是 Document, Field, IndexWriter, Analyzer, Directory。

    下面我们分别介绍一下这五个类的用途:

    Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。

    Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。

    Analyzer 在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。

    IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。

    Directory 这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。

Lucene搜索结果

    Lucene提供了几个基础的类来完成这个过程,它们分别是呢IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。

    Query这是一个抽象类,他有多个实现,比如TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。

    Term 是搜索的基本单位,一个Term对象有两个String类型的域组成。生成一个Term对象可以有如下一条语句来完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一个参数代表了要在文档的哪一个Field上进行查找,第二个参数代表了要查询的关键词。

    TermQuery是抽象类Query的一个子类,它同时也是Lucene支持的最为基本的一个查询类。生成一个TermQuery对象由如下语句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的构造函数只接受一个参数,那就是一个Term对象。

    IndexSearcher用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个IndexSearcher的实例在一个索引上进行操作。

    Hits 是用来保存搜索的结果的。

Lucene建立索引步骤

[1]指定索引源文件夹(dataDir)和索引的文件夹(IndexDir);

[2]构造一个IndexWriter:IndexWriter构造器有三个参数,其中第一 个参数可以是Lucene内建的类 Directory,也可以是File类型的文件夹路径,还可以是String类型的文件夹路径。第二个参数为语法分析器Analyzer,Lucene 自带了几个分析器的,但是对中文支持都不是很好。最后一个参数是要注意的,Lucene Api解释为“true to create the index or overwrite the existing one; false to append to the existing index”,就是说在这里设定是否增量增加索引,在开发的时候得考虑了,设true将导致每次索引都删除原索引重建,但是如果原来不存在索引而设置为 false也将导致lucene抛出找不到指定文件的错误。

[3]构造Document,通过add方法加入字段:

代码

Document doc = new Document();

doc.add(Field.Text(”contens”,new FileReader(f)));

doc.add(Field.UnIndexed(”filename”,f.getCanonicalPath()));

其中Feild方法有很多种,可以去车东的文章查看详细。f为dataDir文件夹中的文本文件。

[4]IndexWriter通过addDocument(doc)加入document对象,此时lucene将启动分词器对Document对象进行分词索引;

[5]调用IndexWriter的optimize方法对索引进行优化,因为在索引过程中难免产生文件碎屑,该方法对文件进行优化可以提高检索效率;

[6]关闭IndexWriter:IndexWriter.close()。

Lucene进行搜索步骤

[1]创建IndexSearcher实例,其构造方法有三个,单参数,可以用String形式的索引文件夹路径;

[2]创建Query :代码

Query query = QueryParser.parse(q,”contents”,new Analyzer());

其中q为查询字符串,“contents”为查询字段。

[3]搜索:代码

Hits hits = indexwriter.search(query)

hits由Document类型组成。可以通过hits.doc(i)获取具体的Document对象

Lucene2.0 Field类的结构

Document可以看作是数据库的一行记录。

Field可以看作是数据库的字段。

Field(String name, byte[] value, Field.Store store)

Field(String name, Reader reader)

Field(String name, Reader reader, Field.TermVector termVector)

Field(String name, String value, Field.Store store, Field.Index index)

Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector)

在Field中有三个内部类:Field.Index,Field.Store,Field.termVector,而构造函数也用到了它们。

注意:termVector是Lucene 1.4新增的它提供一种向量机制来进行模糊查询的这个不常用,默认是false,不管是什么对于一般查询无影响。

它们的不同的组合,在全文检索中有着不同的作用。

方法 切词 索引 存储 用途
Field.Text(String name, String value) Yes Yes Yes 切分词索引并存储,比如:标题,内容字段
Field.Text(String name, Reader value) Yes Yes No 切分词索引不存储,比如:META信息,
不用于返回显示,但需要进行检索内容

Field.Keyword(String name, String value) No Yes Yes 不切分索引并存储,比如:日期字段
Field.UnIndexed(String name, String value) No No Yes 不索引,只存储,比如:文件路径
Field.UnStored(String name, String value) Yes Yes No 只全文索引,不存储

而对于Field(String name, Reader reader)

Field(String name, Reader reader, Field.TermVector termVector)

他们是Field.Index.TOKENIZED和Field.Store.NO的。

中文分词

    Lucene是外国人做的,当然就不带有中文分词引擎。

    词模块对于搜索的重要性不言而喻。例如,没有分词时,搜索“和服”会出现“产品和服务”,搜索“海尔”会出现“海尔德”,搜索“华为”会出现“清华为何”。所以有必要给文本增加词的边界信息以提高检索精确度。

中文分词技术

    现有的分词技术可分为三类:

    基于字符串匹配的分词

    基于理解的分词

    基于统计的分词

    基于字符串匹配的分词技术,这种技术也被称为机械分词。它是按照一定的策略将待分析的汉字串与一个“充分大的”词库中的词条进行匹配。若在词库中找到某个 字符串则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长) 匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词法和分词与标注结合法。常用的几种机械分词方法如下:

正向最大匹配法(由左到右的方向)

逆向最大匹配法(由右到左的方向)

分词引擎:

    MMSeg是一个开放源代码的中文分词软件包,可以方便的和Lucene集成。它实现了MMSEG: A Word Identification System for Mandarin Chinese Text Based on Two Variants of the Maximum Matching Algorithm算法。

    中科院的分词引擎做得不错。有多种语言的版本。

    Cnblogs里有人发布了ICTCLAS的C#版SharpICTCLAS。很优秀的中文分词程序。

    还有C#版的SplitWords等。

    lucene开源中文分词器 IKAnalyzer,猎图网目前就是使用该分词器.

    我曾经为了练手也写过一个小小的分词引擎,词库是盗用”万能五笔”的,用计算机整理了几个小时,缩减成十几万的词库,效果还不错,不过和牛人相比,不是一个级别的:).

PHP下也有开源的中文分词包。分词算法和词库的不同,分词的效果和效率是有千差万别的。我们可以根据自己的需要适当选取,如果你觉得自己有能力完成写出一个更好的搜索和分词引擎,请你收下我这个学生。

推荐的Lucene书籍和网站:

Lucene In Action :Manning - Lucene in Action, A Guide to the Java Search Engine

征服Ajax+Lucene构建搜索引擎

Introduction to Text Indexing with Apache Jakarta Lucene

http://www.onjava.com/pub/a/onjava/2003/01/15/lucene.html

Advanced Text Indexing with Lucene

http://www.onjava.com/pub/a/onjava/2003/03/05/lucene.html

关于Chedong的blog(非常著名,汉语)

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

Lucene全文检索实践

http://www.infor96.com/~nio/comments.php?id=84_0_1_0_C

关于Lucene的基本概念

http://www.cnblogs.com/lucene/archive/2004/12/20/79804.html

Lucene使用者沙龙(为Chedong和一些朋友的沙龙,有ppt和http://blog.cnblog.org/archives/2005/07/luceneaecee.html

Lucene研究之一——起源、现状及初步应用http://jalorsoft.com/holen/holen_lucene_01.html

Lucene研究之二——系统结构分析初步(已阅)

http://jalorsoft.com/holen/holen_lucene_02.html

系统讲了Lucene架构(英文)

http://www-igm.univ-mlv.fr/~dr/XPOSE2003/lucene/node1.html

Doug Cutting(Lucene作者)做的关于Lucene的架构解说

http://lucene.sourceforge.net/talks/pisa/

English StopWords列表

http://www.onjava.com/onjava/2003/01/15/examples/EnglishStopWords.txt

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics