信息时代的生存哲学

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
使用Lucene建立自己的搜索引擎

lucene是一个极其灵活的开放源代码的搜索引擎。

Lucene会直接同你的Web应用程序集成到一起。它是由Jakarta Apache工作组使用Java编写成的。你的Java应用程序能够将Lucene作为任何搜索功能的核心来使用。Lucene能够处理任何类型的文本数据;但是它没有内置对Word、Excel、PDF和XML的支持。但是还是有一些解决方案能够让Lucene支持它们中的每一个。

关于Lucene的重要一点是,它只是一个搜索引擎,因此没有内置Web图形用户界面和Web crawler。要把Lucene集成到你的Web应用程序里,你就要编写一个显示查询表单的servlet或者JSP页面,还要编写另一个列出结果的页面。

用Lucene来建立一个索引

你应用程序的文本内容由Lucene来索引,并被作为一系列索引文件保存在文件系统里。Lucene能够接受代表单篇内容的文档(Document)对象,例如一个Web页面或者PDF文件。你的应用程序就负责将其内容转变成Lucene能够理解的文档对象。

每个文档都是由有一个或者多个的字段(Field)对象。这些字段包含有一个名称和一个值,非常像散裂图里的一个项目(entry)。每个字段都应该对应一段信息,这段信息是同你需要查询或者显示的检索结果相关的。例如,标题应该被用在搜索结果里,因此它会被作为一个字段添加到文档对象里。这些字段可以被索引,也可以不被索引,而原始的数据也可以选择保存在索引里。保存在索引里的字段在创建检索结果页面的时候会很有用。对于搜索没有用处的字段,例如唯一的ID,就不需要被索引,只需要被保存就行了。

字段也可以是标记化了的(tokenized),这就意味着一个分析程序会将输入到字段里的内容分解成搜索引擎能够使用的标记。Lucene带有多个分析程序,但是我只会使用最强大的分析程序——StandardAnalyzer类。

StandardAnalyzer类会将文本的所有内容变成小写的,并去掉一些常用的停顿词(stop word)。停顿词是像“a”、“the”和“in”这样的词,它们都是内容里非常常见的词,但是对搜索却一点用处都没有。分析程序也会分析搜索查询,这就意味着查询会找到匹配的部分。例如,这段文本“The dog is a golden retriever(这条狗是一只金毛猎犬)”,就会被处理为“dog golden retriever”作为索引。当用户搜索“a Golden Dog”的时候,分析程序会处理这个查询,并将其转变为“golden dog”,这就符合我们的内容了。

我们的例子准备使用数据访问对象(Data Access Object,DAO)的商务对象(business object),前者是Java应用程序开发的一个常见模式。我要使用的DAO——ProductDAOListing A

为了让这个演示程序简单,我不准备使用数据库,DAO也只会包含产品(Product)对象的一个集合。在本例里,我会采用Listing B里的产品对象,并将它们转变成为用于索引的文档。

索引符(Indexer)类在Listing C里,它将负责把Product转换成为Lucene文档,还负责创建Lucene索引。

产品类里的字段是ID名、简短描述和详细描述。通过使用字段(Field)类的UnIndexed方法,ID会被作为一个非索引的非标记字段被保存。通过使用字段类的Keyword方法,名称和简短描述会被作为索引的非标记字段被保存。搜索引擎会对内容字段进行查询,而内容字段里会包含有产品的名称、简短描述和详细描述字段。

在所有的文档都添加完之后,就要优化索引并关闭索引编写器,这样你才能够使用索引。Lucene的大多数实现都要使用增量索引(incremental indexing),在增量索引里,已经在索引里的文档都是独立更新的,而不是每次先删除索引再创建一个新的。

运行查询

创建一个查询并在索引里搜索结果要比创建一个索引简单。你的应用程序会要求使用者提供一个搜索查询,这个查询可以是一个简单的词语。Lucene拥有一些更加高级的查询(Query)类,用于布尔搜索或者整句搜索。

高级查询的一个例子是”Mutual Fund”(互惠基金)AND stock*(股票),它会搜索包含有短语Mutual Fund和以stock开头的词(例如stocks、stock或者甚至是stockings)的文档。


获取更多关于Lucene里查询的信息
Lucene Web网站里的句法页面会提供更加详细的信息。



搜索符(Searcher)类放在Listing D里,它负责在Lucene索引里查找你所使用的词语。对于本篇演示程序而言,我使用了一个简单的查询,它只是一个字符串,而没有使用任何高级查询功能。我用QueryParser类从查询字符串里创建了一个查询(Query)对象,QueryParser这个类会使用StandardAnalyzer类将查询字符串分解成标记,再去掉停顿词,然后将这个字符串转换成小写的。

这个查询被传递给一个IndexSearcher对象。IndexSearcher会在索引的文件系统里被初始化。IndexSearcher的搜索方法将接受这个查询并返回一个命中(Hits)对象。这个命中对象包含有作为Lucene文档对象的检索结果,以及结果的长度。使用命中对象的Doc方法将取回命中对象里的每个文档。

文档对象包含有我添加到索引符文档里的字段。这些字段中的一些被保存了,但是没有被标记化,你可以将它们从文档里提取出来。示例应用程序会用搜索引擎运行一个查询,然后显示它所找到的产品名称。


运行演示程序

要运行本文里的示例程序,你需要从Lucene的Web网站下载最新版本的Lucene二进制发布版本(binary distribution)。Lucene发行版的lucene-1.3-rc1.jar文件需要被添加到你Java类的路径下才能够运行这个演示程序。演示程序会在运行com.greenninja.lucene.Demo类的目录下创建一个叫做index的索引目录。你还需要安装好JDK。一行典型的命令是:java -cp c:\java\lucene-1.3-rc1\lucene-1.3-rc1.jar;. com.greenninja.lucene.Demo(见A)。本例所使用的示例数据包含在ProductDAO类里。这个查询是演示(Demo)类的一部分。



图A

 

命令行示例

posted on 2004-08-11 13:06  信息时代的生存哲学  阅读(2143)  评论(1)    收藏  举报