使用 Apache Lucene 搜索文本.docx

上传人:b****3 文档编号:3531405 上传时间:2022-11-23 格式:DOCX 页数:16 大小:47.50KB
下载 相关 举报
使用 Apache Lucene 搜索文本.docx_第1页
第1页 / 共16页
使用 Apache Lucene 搜索文本.docx_第2页
第2页 / 共16页
使用 Apache Lucene 搜索文本.docx_第3页
第3页 / 共16页
使用 Apache Lucene 搜索文本.docx_第4页
第4页 / 共16页
使用 Apache Lucene 搜索文本.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

使用 Apache Lucene 搜索文本.docx

《使用 Apache Lucene 搜索文本.docx》由会员分享,可在线阅读,更多相关《使用 Apache Lucene 搜索文本.docx(16页珍藏版)》请在冰豆网上搜索。

使用 Apache Lucene 搜索文本.docx

使用ApacheLucene搜索文本

使用ApacheLucene搜索文本

轻松为应用程序构建搜索和索引功能

AmolSonawane,资深软件工程师,EMC

AmolSonawane是一名高级软件工程师,拥有班加罗尔国际信息技术学院的研究生学位。

他为许多领域设计和开发软件,比如供应链管理、企业应用程序集成和商业智能。

他可以使用J2EE技术和框架(Struts和Spring)开发应用程序。

他与妻子Anuja居住在印度普内。

除了编程,他还喜欢摄影、下棋和字谜。

简介:

 本文将探讨ApacheLucene——性能卓越、功能全面的文本搜索引擎库。

我们将学习Lucene架构及其核心API。

学习如何使用Lucene进行跨平台全文本搜索、建立索引、显示结果,以及如何扩展搜索。

标记本文!

发布日期:

 2009年9月14日

级别:

 初级

其他语言版本:

 英文

建议:

 0 (添加评论)

平均分(共0个评分)

简介

Lucene是一个开源、高度可扩展的搜索引擎库,可以从ApacheSoftwareFoundation获取。

您可以将Lucene用于商业和开源应用程序。

Lucene强大的API主要关注文本索引和搜索。

它可以用于为各种应用程序构建搜索功能,比如电子邮件客户端、邮件列表、Web搜索、数据库搜索等等。

Wikipedia、TheServerSide、jGuru和LinkedIn等网站都使用了Lucene。

Lucene还为EclipseIDE、Nutch(著名的开源Web搜索引擎)以及IBM®、AOL和Hewlett-Packard等公司提供搜索功能。

Lucene已经兼容许多其他编程语言,包括Perl、Python、C++和.NET。

到2009年7月30日止,用于Java™编程语言的最新版Lucene为V2.4.1。

Lucene功能众多:

∙拥有强大、准确、有效的搜索算法。

∙计算每个文档匹配给定查询的分数,并根据分数返回最相关的文档。

∙支持许多强大的查询类型,比如PhraseQuery、WildcardQuery、RangeQuery、FuzzyQuery、BooleanQuery等。

∙支持解析人们输入的丰富查询表达式。

∙允许用户使用定制排序、过滤和查询表达式解析扩展搜索行为。

∙使用基于文件的锁定机制保护并发索引修改。

∙允许同时搜索和编制索引。

回页首

使用Lucene构建应用程序

如图1所示,使用Lucene构建功能全面的搜索应用程序主要涉及编制数据索引、搜索数据和显示搜索结果几个方面。

图1.使用Lucene构建应用程序的步骤

本文从使用LuceneV2.4.1和Java技术开发的样例应用程序中挑选了一些代码片段。

示例应用程序为存储在属性文件中一组电子邮件文档编制索引,并展示了如何使用Lucene的查询API搜索索引。

该示例还让您熟悉基本的索引操作。

回页首

为数据编制索引

Lucene允许您为任何文本格式的数据编制索引。

Lucene可以用于几乎任何数据源以及从中提取的文本信息。

您可以使用Lucene编制索引并搜索HTML文档、Microsoft®Word文档、PDF文件中存储的数据。

编制数据索引的第一步是让数据变成一个简单的文本格式。

您可以使用定制解析器和数据转换器实现这一点。

编制索引的过程

编制索引是将文本数据转换为有利于快速搜索的格式。

这类似于书本后面的索引:

为您指出主题在书中出现的位置。

Lucene将输入数据存储在名为逆序索引的数据结构中,该数据结构以索引文件集的形式存储在文件系统或内存中。

大部分Web搜索引擎都使用逆序索引。

它允许用户执行快速关键字查询,查找匹配给定查询的文档。

在将文本数据添加到索引前,由分析程序(使用分析过程)进行处理。

分析

分析是将文本数据转换为搜索基本单位(称为项(term))的过程。

在分析过程中,文本数据将经历多项操作:

提取单词、移除通用单词、忽略标点符号、将单词变为词根形式、将单词变成小写等等。

分析过程发生在编制索引和查询解析之前。

分析将文本数据转换为标记,这些标记将作为项添加到Lucene索引中。

Lucene有多种内置分析程序,比如SimpleAnalyzer、StandardAnalyzer、StopAnalyzer、SnowballAnalyzer等。

它们在标记文本和应用过滤器的方式上有所区别。

因为分析在编制索引之前移除单词,它减少了索引的大小,但是不利用精确的查询过程。

您可以使用Lucene提供的基本构建块创建定制分析程序,以自己的方式控制分析过程。

表1展示了一些内置分析程序及其处理数据的方式。

表1.Lucene的内置分析程序

分析程序

对文本数据的操作

WhitespaceAnalyzer

分解空白处的标记

SimpleAnalyzer

分解非字母字符的文本,并将文本转为小写形式

StopAnalyzer

移除虚字(stopword)——对检索无用的字,并将文本转为小写形式

StandardAnalyzer

根据一种复杂语法(识别电子邮件地址、缩写、中文、日文、韩文字符、字母数字等等)标记文本

将文本转为小写形式

移除虚字

核心索引编制类

Directory

表示索引文件存储位置的抽象类。

有两个常用的子类:

∙FSDirectory—在实际文件系统中存储索引的Directory实现。

该类对于大型索引非常有用。

∙RAMDirectory—在内存中存储所有索引的实现。

该类适用于较小的索引,可以完整加载到内存中,在应用程序终止之后销毁。

由于索引保存在内存中,所以速度相对较快。

Analyzer

正如上文所述,分析程序负责处理文本数据并将其转换为标记存储在索引中。

在编制索引前,IndexWriter接收用于标记数据的分析程序。

要为文本编制索引,您应该使用适用于该文本语言的分析程序。

默认分析程序适用于英语。

在Lucene沙盒中还有其他分析程序,包括用于中文、日文和韩文的分析程序。

IndexDeletionPolicy

该接口用来实现从索引目录中定制删除过时提交的策略。

默认删除策略是KeepOnlyLastCommitDeletionPolicy,该策略仅保留最近的提交,并在完成一些提交之后立即移除所有之前的提交。

IndexWriter

创建或维护索引的类。

它的构造函数接收布尔值,确定是否创建新索引,或者打开现有索引。

它提供在索引中添加、删除和更新文档的方法。

对索引所做的更改最初缓存在内存中,并周期性转储到索引目录。

IndexWriter公开了几个控制如何在内存中缓存索引并写入磁盘的字段。

对索引的更改对于IndexReader不可见,除非调用IndexWriter的提交或关闭方法。

IndexWriter创建一个目录锁定文件,以通过同步索引更新保护索引不受破坏。

IndexWriter允许用户指定可选索引删除策略。

列表1.使用LuceneIndexWriter

//CreateinstanceofDirectorywhereindexfileswillbestored

DirectoryfsDirectory=FSDirectory.getDirectory(indexDirectory);

/*Createinstanceofanalyzer,whichwillbeusedtotokenize

theinputdata*/

AnalyzerstandardAnalyzer=newStandardAnalyzer();

//Createanewindex

booleancreate=true;

//Createtheinstanceofdeletionpolicy

IndexDeletionPolicydeletionPolicy=newKeepOnlyLastCommitDeletionPolicy();

indexWriter=newIndexWriter(fsDirectory,standardAnalyzer,create,

deletionPolicy,IndexWriter.MaxFieldLength.UNLIMITED);

将数据添加到索引

将文本数据添加到索引涉及到两个类。

Field表示搜索中查询或检索的数据片。

Field类封装一个字段名称及其值。

Lucene提供了一些选项来指定字段是否需要编制索引或分析,以及值是否需要存储。

这些选项可以在创建字段实例时传递。

下表展示了Field元数据选项的详细信息。

表2.Field元数据选项的详细信息

选项

描述

Field.Store.Yes

用于存储字段值。

适用于显示搜索结果的字段—例如,文件路径和URL。

Field.Store.No

没有存储字段值—例如,电子邮件消息正文。

Field.Index.No

适用于未搜索的字段—仅用于存储字段,比如文件路径。

Field.Index.ANALYZED

用于字段索引和分析—例如,电子邮件消息正文和标题。

Field.Index.NOT_ANALYZED

用于编制索引但不分析的字段。

它在整体中保留字段的原值—例如,日期和个人名称。

Document是一个字段集合。

Lucene也支持推进文档和字段,这在给某些索引数据赋予重要性时非常有用。

给文本文件编制索引包括将文本数据封装在字段中、创建文档、填充字段,使用IndexWriter向索引添加文档。

列表2展示向索引添加数据的示例。

列表2.向索引添加数据

/*Step1.Preparethedataforindexing.Extractthedata.*/

Stringsender=properties.getProperty("sender");

Stringdate=properties.getProperty("date");

Stringsubject=properties.getProperty("subject");

Stringmessage=properties.getProperty("message");

Stringemaildoc=file.getAbsolutePath();

/*Step2.WrapthedataintheFieldsandaddthemtoaDocument*/

FieldsenderField=

newField("sender",sender,Field.Store.YES,Field.Index.NOT_ANALYZED);

Fieldemaildatefield=

newField("date",date,Field.Store.NO,Field.Index.NOT_ANALYZED);

FieldsubjectField=

newField("subject",subject,Field.Store.YES,Field.Index.ANALYZED);

Fieldmessagefield=

newField("message",message,Field.Store.NO,Field.Index.ANALYZED);

FieldemailDocField=

newField("emailDoc",emaildoc,Field.Store.YES,

Field.Index.NO);

Documentdoc=newDocument();

//AddthesefieldstoaLuceneDocument

doc.add(senderField);

doc.add(emaildatefield);

doc.add(subjectField);

doc.add(messagefield);

doc.add(emailDocField);

//Step3:

AddthisdocumenttoLuceneIndex.

indexWriter.addDocument(doc);

回页首

搜索索引数据

搜索是在索引中查找单词并查找包含这些单词的文档的过程。

使用Lucene的搜索API构建的搜索功能非常简单明了。

本小节讨论Lucene搜索API的主要类。

Searcher

Searcher是一个抽象基类,包含各种超负荷搜索方法。

IndexSearcher是一个常用的子类,允许在给定的目录中存储搜索索引。

Search方法返回一个根据计算分数排序的文档集合。

Lucene为每个匹配给定查询的文档计算分数。

IndexSearcher是线程安全的;一个实例可以供多个线程并发使用。

Term

Term是搜索的基本单位。

它由两部分组成:

单词文本和出现该文本的字段的名称。

Term对象也涉及索引编制,但是可以在Lucene内部创建。

Query和子类

Query是一个用于查询的抽象基类。

搜索指定单词或词组涉及到在项中包装它们,将项添加到查询对象,将查询对象传递到IndexSearcher的搜索方法。

Lucene包含各种类型的具体查询实现,比如TermQuery、BooleanQuery、PhraseQuery、PrefixQuery、RangeQuery、MultiTermQuery、FilteredQuery、SpanQuery等。

以下部分讨论Lucene查询API的主查询类。

TermQuery

搜索索引最基本的查询类型。

可以使用单个项构建TermQuery。

项值应该区分大小写,但也并非全是如此。

注意,传递的搜索项应该与文档分析得到的项一致,因为分析程序在构建索引之前对原文本执行许多操作。

例如,考虑电子邮件标题“JobopeningsforJavaProfessionalsatBangalore”。

假设您使用StandardAnalyzer编制索引。

现在如果我们使用TermQuery搜索“Java”,它不会返回任何内容,因为本文本应该已经规范化,并通过StandardAnalyzer转成小写。

如果搜索小写单词“java”,它将返回所有标题字段中包含该单词的邮件。

列表3.使用TermQuery搜索

//Searchmailshavingtheword"java"inthesubjectfield

SearcherindexSearcher=newIndexSearcher(indexDirectory);

Termterm=newTerm("subject","java");

QuerytermQuery=newTermQuery(term);

TopDocstopDocs=indexSearcher.search(termQuery,10);

RangeQuery

您可以使用RangeQuery在某个范围内搜索。

索引中的所有项都以字典顺序排列。

Lucene的RangeQuery允许用户在某个范围内搜索项。

该范围可以使用起始项和最终项(包含两端或不包含两端均可)指定。

列表4.在某个范围内搜索

/*RangeQueryexample:

Searchmailsfrom01/06/2009to6/06/2009

bothinclusive*/

Termbegin=newTerm("date","20090601");

Termend=newTerm("date","20090606");

Queryquery=newRangeQuery(begin,end,true);

PrefixQuery

您可以使用PrefixQuery通过前缀单词进行搜索,该方法用于构建一个查询,该查询查找包含以指定单词前缀开始的词汇的文档。

列表5.使用PrefixQuery搜索

//Searchmailshavingsenderfieldprefixedbytheword'job'

PrefixQueryprefixQuery=newPrefixQuery(newTerm("sender","job"));

PrefixQueryquery=newPrefixQuery(newTerm("sender","job"));

BooleanQuery

您可以使用BooleanQuery组合任何数量的查询对象,构建强大的查询。

它使用query和一个关联查询的子句,指示查询是应该发生、必须发生还是不得发生。

在BooleanQuery中,子句的最大数量默认限制为1,024。

您可以调用setMaxClauseCount方法设置最大子句数。

列表6.使用BooleanQuery进行搜索

//Searchmailshaveboth'java'and'bangalore'inthesubjectfield

Queryquery1=newTermQuery(newTerm("subject","java"));

Queryquery2=newTermQuery(newTerm("subject","bangalore"));

BooleanQueryquery=newBooleanQuery();

query.add(query1,BooleanClause.Occur.MUST);

query.add(query2,BooleanClause.Occur.MUST);

PhraseQuery

您可以使用PhraseQuery进行短语搜索。

PhraseQuery匹配包含特定单词序列的文档。

PhraseQuery使用索引中存储的项的位置信息。

考虑匹配的项之间的距离称为slop。

默认情况下,slop的值为零,这可以通过调用setSlop方法进行设置。

PhraseQuery还支持多个项短语。

列表7.使用PhraseQuery进行搜索

/*PhraseQueryexample:

Searchmailsthathavephrase'jobopeningj2ee'

inthesubjectfield.*/

PhraseQueryquery=newPhraseQuery();

query.setSlop

(1);

query.add(newTerm("subject","job"));

query.add(newTerm("subject","opening"));

query.add(newTerm("subject","j2ee"));

WildcardQuery

WildcardQuery实现通配符搜索查询,这允许您搜索arch*(可以查找包含architect、architecture等)之类的单词。

使用两个标准通配符:

∙*表示零个以上

∙?

表示一个以上

如果使用以通配符查询开始的模式进行搜索,则可能会引起性能的降低,因为这需要查询索引中的所有项以查找匹配文档。

列表8.使用WildcardQuery进行搜索

//Searchfor'arch*'tofinde-mailmessagesthathaveword'architect'inthesubject

field./

Queryquery=newWildcardQuery(newTerm("subject","arch*"));

FuzzyQuery

您可以使用FuzzyQuery搜索类似项,该类匹配类似于指定单词的单词。

类似度测量基于Levenshtein(编辑距离)算法进行。

在列表9中,FuzzyQuery用于查找与拼错的单词“admnistrtor”最接近的项,尽管这个错误单词没有索引。

列表9.使用FuzzyQuery进行搜索

/*Searchforemailsthathavewordsimilarto'admnistrtor'inthe

subjectfield.Notewehavemisspelledadmnistrtorhere.*/

Queryquery=newFuzzyQuery(newTerm("subject","admnistrtor"));

QueryParser

QueryParser对于解析人工输入的查询字符非常有用。

您可以使用它将用户输入的查询表达式解析为Lucene查询对象,这些对象可以传递到IndexSearcher的搜索方法。

它可以解析丰富的查询表达式。

QueryParser内部将人们输入的查询字符串转换为一个具体的查询子类。

您需要使用反斜杠(\)将*、?

等特殊字符进行转义。

您可以使用运算符AND、OR和NOT构建文本布尔值查询。

列表10.搜索人工输入的查询表达式

QueryParserqueryParser=newQueryParser("subject",newStandardAnalyzer());

//Searchforemailsthatcontainthewords'jobopenings'and'.net'and'pune'

Queryquery=queryParser.parse("jobopeningsAND.netANDpune");

 

回页首

显示搜索结果

IndexSearcher返回一组对分级搜索结果(如匹配给定查询的文档)的引用。

您可以使用IndexSearcher的搜索方法确定需要检索的最优先搜索结果数量。

可以在此基础上构建定制分页。

您可以添加定制Web应用程序或桌面应用程序来显示搜索结果。

检索搜索结果涉及的主要类包括ScoreDoc和TopDocs。

ScoreDoc

搜索结果中包含一个指向文档的简单指针。

这可以封装文档索引中文档的位置以及Lucene计算的分数。

TopDocs

封装搜索结果以及ScoreDoc的总数。

以下代码片段展示了如何检索搜索结果中包含的文档。

列表11.展示搜索结果

/*Firstparameteristhequerytobeexecutedand

secondparameterindicatesthenoofsearchre

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1