在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Lucene搜索引擎 → java lucene搜索 常用示例源码下载

java lucene搜索 常用示例源码下载

Lucene搜索引擎

下载此实例
  • 开发语言:Java
  • 实例大小:0.74M
  • 下载次数:39
  • 浏览次数:348
  • 发布时间:2015-12-26
  • 实例类别:Lucene搜索引擎
  • 发 布 人:crazycode
  • 文件格式:.zip
  • 所需积分:2
 相关标签: Lucene java 搜索

实例介绍

【实例简介】

简介

Lucene 是一个开源、高度可扩展的搜索引擎库,可以从 Apache Software Foundation 获取。您可以将 Lucene 用于商业和开源应用程序。Lucene 强大的 API 主要关注文本索引和搜索。它可以用于为各种应用程序构建搜索功能,比如电子邮件客户端、邮件列表、Web 搜索、数据库搜索等等。Wikipedia、TheServerSide、jGuru 和 LinkedIn 等网站都使用了 Lucene。

Lucene 还为 Eclipse IDE、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 构建应用程序的步骤
使用 Lucene 构建应用程序的步骤

本文从使用 Lucene V2.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 移除虚字(stop word)—— 对检索无用的字,并将文本转为小写形式
StandardAnalyzer 根据一种复杂语法(识别电子邮件地址、缩写、中文、日文、韩文字符、字母数字等等)标记文本
将文本转为小写形式
移除虚字

核心索引编制类

Directory表示索引文件存储位置的抽象类。有两个常用的子类:
  • FSDirectory— 在实际文件系统中存储索引的 Directory 实现。该类对于大型索引非常有用。
  • RAMDirectory— 在内存中存储所有索引的实现。该类适用于较小的索引,可以完整加载到内存中,在应用程序终止之后销毁。由于索引保存在内存中,所以速度相对较快。
Analyzer正如上文所述,分析程序负责处理文本数据并将其转换为标记存储在索引中。在编制索引前,IndexWriter 接收用于标记数据的分析程序。要为文本编制索引,您应该使用适用于该文本语言的分析程序。

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

IndexDeletionPolicy该接口用来实现从索引目录中定制删除过时提交的策略。默认删除策略是 KeepOnlyLastCommitDeletionPolicy,该策略仅保留最近的提交,并在完成一些提交之后立即移除所有之前的提交。IndexWriter创建或维护索引的类。它的构造函数接收布尔值,确定是否创建新索引,或者打开现有索引。它提供在索引中添加、删除和更新文档的方法。

对索引所做的更改最初缓存在内存中,并周期性转储到索引目录。IndexWriter 公开了几个控制如何在内存中缓存索引并写入磁盘的字段。对索引的更改对于 IndexReader 不可见,除非调用 IndexWriter 的提交或关闭方法。IndexWriter 创建一个目录锁定文件,以通过同步索引更新保护索引不受破坏。IndexWriter 允许用户指定可选索引删除策略。

列表 1. 使用 Lucene IndexWriter
//Create instance of Directory where index files will be stored
Directory fsDirectory =  FSDirectory.getDirectory(indexDirectory);
/* Create instance of analyzer, which will be used to tokenize
the input data */
Analyzer standardAnalyzer = new StandardAnalyzer();
//Create a new index
boolean create = true;
//Create the instance of deletion policy
IndexDeletionPolicy deletionPolicy = new KeepOnlyLastCommitDeletionPolicy(); 
indexWriter =new IndexWriter(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. 向索引添加数据
/*Step 1. Prepare the data for indexing. Extract the data. */

String sender = properties.getProperty("sender");
String date = properties.getProperty("date");
String subject = properties.getProperty("subject");
String message = properties.getProperty("message");
String emaildoc = file.getAbsolutePath();

/* Step 2. Wrap the data in the Fields and add them to a Document */

Field senderField =
	new Field("sender",sender,Field.Store.YES,Field.Index.NOT_ANALYZED);
Field emaildatefield = 
		new Field("date",date,Field.Store.NO,Field.Index.NOT_ANALYZED); 
Field subjectField = 
	new Field("subject",subject,Field.Store.YES,Field.Index.ANALYZED);
Field messagefield = 
			new Field("message",message,Field.Store.NO,Field.Index.ANALYZED);
Field emailDocField =
	new Field("emailDoc",emaildoc,Field.Store.YES,
						Field.Index.NO);

Document doc = new Document();
// Add these fields to a Lucene Document
doc.add(senderField);
doc.add(emaildatefield);
doc.add(subjectField);
doc.add(messagefield);
doc.add(emailDocField);

//Step 3: Add this document to Lucene Index.
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。项值应该区分大小写,但也并非全是如此。注意,传递的搜索项应该与文档分析得到的项一致,因为分析程序在构建索引之前对原文本执行许多操作。

例如,考虑电子邮件标题 “Job openings for Java Professionals at Bangalore”。假设您使用 StandardAnalyzer 编制索引。现在如果我们使用 TermQuery 搜索 “Java”,它不会返回任何内容,因为本文本应该已经规范化,并通过 StandardAnalyzer 转成小写。如果搜索小写单词 “java”,它将返回所有标题字段中包含该单词的邮件。

列表 3. 使用 TermQuery 搜索
//Search mails having the word "java" in the subject field
Searcher indexSearcher = new IndexSearcher(indexDirectory);
Term term = new Term("subject","java");
Query termQuery = new TermQuery(term);	 
TopDocs topDocs = indexSearcher.search(termQuery,10);
RangeQuery您可以使用 RangeQuery 在某个范围内搜索。索引中的所有项都以字典顺序排列。Lucene 的 RangeQuery 允许用户在某个范围内搜索项。该范围可以使用起始项和最终项(包含两端或不包含两端均可)指定。
列表 4. 在某个范围内搜索
/* RangeQuery example:Search mails from 01/06/2009 to 6/06/2009 
both inclusive */
Term begin = new Term("date","20090601");
Term end = new Term("date","20090606");
Query query = new RangeQuery(begin, end, true);
PrefixQuery您可以使用 PrefixQuery 通过前缀单词进行搜索,该方法用于构建一个查询,该查询查找包含以指定单词前缀开始的词汇的文档。
列表 5. 使用 PrefixQuery 搜索
//Search mails having sender field prefixed by the word 'job'
PrefixQuery prefixQuery = new PrefixQuery(new Term("sender","job"));
PrefixQuery query = new PrefixQuery(new Term("sender","job"));
BooleanQuery您可以使用 BooleanQuery 组合任何数量的查询对象,构建强大的查询。它使用 query 和一个关联查询的子句,指示查询是应该发生、必须发生还是不得发生。在 BooleanQuery 中,子句的最大数量默认限制为 1,024。您可以调用 setMaxClauseCount 方法设置最大子句数。
列表 6. 使用 BooleanQuery 进行搜索
// Search mails have both 'java' and 'bangalore' in the subject field
Query query1 = new TermQuery(new Term("subject","java"));
Query query2 = new TermQuery(new Term("subject","bangalore"));
BooleanQuery query = new BooleanQuery();
query.add(query1,BooleanClause.Occur.MUST);
query.add(query2,BooleanClause.Occur.MUST);
PhraseQuery您可以使用 PhraseQuery 进行短语搜索。PhraseQuery 匹配包含特定单词序列的文档。PhraseQuery 使用索引中存储的项的位置信息。考虑匹配的项之间的距离称为 slop。默认情况下,slop 的值为零,这可以通过调用 setSlop 方法进行设置。PhraseQuery 还支持多个项短语。
列表 7. 使用 PhraseQuery 进行搜索
/* PhraseQuery example: Search mails that have phrase 'job opening j2ee'
   in the subject field.*/
PhraseQuery query = new PhraseQuery();
query.setSlop(1);
query.add(new Term("subject","job"));
query.add(new Term("subject","opening"));
query.add(new Term("subject","j2ee"));
WildcardQueryWildcardQuery 实现通配符搜索查询,这允许您搜索 arch*(可以查找包含 architect、architecture 等)之类的单词。使用两个标准通配符:
  • * 表示零个以上
  • ? 表示一个以上
如果使用以通配符查询开始的模式进行搜索,则可能会引起性能的降低,因为这需要查询索引中的所有项以查找匹配文档。
列表 8. 使用 WildcardQuery 进行搜索
//Search for 'arch*' to find e-mail messages that have word 'architect' in the subject
field./
Query query = new WildcardQuery(new Term("subject","arch*"));
FuzzyQuery您可以使用 FuzzyQuery 搜索类似项,该类匹配类似于指定单词的单词。类似度测量基于 Levenshtein(编辑距离)算法进行。在列表 9 中,FuzzyQuery 用于查找与拼错的单词 “admnistrtor” 最接近的项,尽管这个错误单词没有索引。
列表 9. 使用 FuzzyQuery 进行搜索
/* Search for emails that have word similar to 'admnistrtor' in the
subject field. Note we have misspelled admnistrtor here.*/
Query query = new FuzzyQuery(new Term("subject", "admnistrtor"));
QueryParserQueryParser 对于解析人工输入的查询字符非常有用。您可以使用它将用户输入的查询表达式解析为 Lucene 查询对象,这些对象可以传递到 IndexSearcher 的搜索方法。它可以解析丰富的查询表达式。 QueryParser 内部将人们输入的查询字符串转换为一个具体的查询子类。您需要使用反斜杠(\)将 *、? 等特殊字符进行转义。您可以使用运算符 AND、OR 和 NOT 构建文本布尔值查询。
列表 10. 搜索人工输入的查询表达式
QueryParser queryParser = new QueryParser("subject",new StandardAnalyzer());
// Search for emails that contain the words 'job openings' and '.net' and 'pune'
Query query = queryParser.parse("job openings AND .net AND pune");

显示搜索结果

IndexSearcher 返回一组对分级搜索结果(如匹配给定查询的文档)的引用。您可以使用 IndexSearcher 的搜索方法确定需要检索的最优先搜索结果数量。可以在此基础上构建定制分页。您可以添加定制 Web 应用程序或桌面应用程序来显示搜索结果。检索搜索结果涉及的主要类包括 ScoreDoc 和 TopDocs。

ScoreDoc搜索结果中包含一个指向文档的简单指针。这可以封装文档索引中文档的位置以及 Lucene 计算的分数。TopDocs封装搜索结果以及 ScoreDoc 的总数。

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

列表 11. 展示搜索结果
/* First parameter is the query to be executed and 
   second parameter indicates the no of search results to fetch */
   TopDocs topDocs = indexSearcher.search(query,20);	
   System.out.println("Total hits " topDocs.totalHits);

   // Get an array of references to matched documents
   ScoreDoc[] scoreDosArray = topDocs.scoreDocs;	
   for(ScoreDoc scoredoc: scoreDosArray){
      //Retrieve the matched document and show relevant details
      Document doc = indexSearcher.doc(scoredoc.doc);
      System.out.println("\nSender: " doc.getField("sender").stringValue());
      System.out.println("Subject: " doc.getField("subject").stringValue());
      System.out.println("Email file location: "
					 doc.getField("emailDoc").stringValue());	
   }

基本的索引操作

基本的索引操作包括移除和提升文档。

从索引中移除文档

应用程序常常需要使用最新的数据更新索引并移除较旧的数据。例如,在 Web 搜索引擎中,索引需要定期更新,因为总是需要添加新网页,移除不存在的网页。Lucene 提供了 IndexReader 接口允许您对索引执行这些操作。

IndexReader 是一个提供各种方法访问索引的抽象类。Lucene 内部引用文档时使用文档编号,该编号可以在向索引添加或从中移除文档时更改。文档编号用于访问索引中的文档。IndexReader 不得用于更新目录中的索引,因为已经打开了 IndexWriter。IndexReader 在打开时总是搜索索引的快照。对索引的任何更改都可以看到,直到再次打开 IndexReader。使用 Lucene 重新打开它们的 IndexReader 可以看到最新的索引更新。

列表 12. 从索引中删除文档
// Delete all the mails from the index received in May 2009.
IndexReader indexReader = IndexReader.open(indexDirectory);
indexReader.deleteDocuments(new Term("month","05"));
//close associate index files and save deletions to disk
indexReader.close();

提升文档和字段

有时您需要给某些索引数据更高的重要级别。您可以通过设置文档或字段的提升因子实现这一点。默认情况下,所有文档和字段的默认提升因子都是 1.0。

列表 13. 提升字段
if(subject.toLowerCase().indexOf("pune") != -1){
// Display search results that contain pune in their subject first by setting boost factor
	subjectField.setBoost(2.2F);
}
//Display search results that contain 'job' in their sender email address
if(sender.toLowerCase().indexOf("job")!=-1){	
	luceneDocument.setBoost(2.1F);
}

扩展搜索

Lucene 提供一个称为排序 的高级功能。您可以根据指示文档在索引中相对位置的字段对搜索结果进行排序。用于排序的字段必须编制索引但不得标记。搜索字段中可以放入 4 种可能的项值:整数值、long 值、浮点值和字符串。

还可以通过索引顺序排序搜索结果。Lucene 通过降低相关度(比如默认的计算分数)对结果排序。排序的顺序是可以更改的。

列表 14. 排序搜索结果
/* Search mails having the word 'job' in subject and return results
   sorted by sender's email in descending order.
 */
SortField sortField = new SortField("sender", true);	
Sort sortBySender = new Sort(sortField);
WildcardQuery query = new WildcardQuery(new Term("subject","job*"));
TopFieldDocs topFieldDocs = 
			indexSearcher.search(query,null,20,sortBySender);
//Sorting by index order
topFieldDocs = indexSearcher.search(query,null,20,Sort.INDEXORDER);

Filtering 是限制搜索空间,只允许某个文档子集作为搜索范围的过程。您可以使用该功能实现对搜索结果进行再次搜索,或者在搜索结果上实现安全性。Lucene 带有各种内置的过滤器,比如 BooleanFilter、CachingWrapperFilter、ChainedFilter、DuplicateFilter、PrefixFilter、QueryWrapperFilter、RangeFilter、RemoteCachingWrapperFilter、SpanFilter 等。Filter 可以传递到 IndexSearcher 的搜索方法,以过滤匹配筛选标准的筛选文档。

列表 15. 筛选搜索结果
/*Filter the results to show only mails that have sender field 
prefixed with 'jobs' */
Term prefix = new Term("sender","jobs");
Filter prefixFilter = new PrefixFilter(prefix);
WildcardQuery query = new WildcardQuery(new Term("subject","job*"));
indexSearcher.search(query,prefixFilter,20);

结束语

Lucene 是来自 Apache 的一个非常流行的开源搜索库, 它为应用程序提供了强大的索引编制和搜索功能。它提供了一个简单易用的 API,只需要稍微了解索引编制和搜索的原理即可使用。在本文中,您学习了 Lucene 架构及其核心 API。

Lucene 为许多知名网站和组织提供了各种强大的搜索功能。它还兼容许多其他编程语言。Lucene 有一个活跃的大型技术用户社区。如果您需要一些易用、可扩展以及高性能的开源搜索库,Apache Lucene 是一个极佳的选择。

【实例截图】

【核心代码】

package example.lucene;

import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixFilter;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;

/**
 * This class demonstrates the usage of Lucene's Indexing and Searching APIs.
 * The sample code comes with a set of input property files that represent
 * email messages of a user. This class has various methods that read the input
 * property files, indexes various fields and provides search on the 
 * indexed data.
 *
 * @author  Amol Sonawane
 */
public class LuceneDemo {

	//a path to directory where Lucene will store index files
	private static String indexDirectory = "./indexdir";
	// a path to directory which contains data files that need to be indexed
	private static String dataDirectory = "./datadir";
	
	private Searcher indexSearcher;
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException, IOException {
		
		if(args.length < 2){
			System.out.println("\nInsufficient arguments: "  
					"\nFirst argument  : Location of the directory where "  
					"index is"  
					"\nSecond argument : Location of directory where data "  
					"files are stored.");
			System.exit(0);
		}
		
		indexDirectory = args[0] ;
		dataDirectory =  args[1] ;
		
		
		LuceneDemo luceneDemo = new LuceneDemo();		
		//create Lucene index
		luceneDemo.createLuceneIndex();
		//create IndexSearcher
		luceneDemo.createIndexSearcher();
		luceneDemo.termQueryExample();
		luceneDemo.rangeQueryExample();
		luceneDemo.prefixQueryExample();
		luceneDemo.booleanQueryExample();
		luceneDemo.phraseQueryExample();
		luceneDemo.wildCardQueryExample();
		luceneDemo.fuzzyQueryExample();
		luceneDemo.queryParserExample();
		luceneDemo.fieldBoostFactorExample();
		luceneDemo.sortBySenderExample();
		luceneDemo.filterExample();
		luceneDemo.deletDocumentFromIndex();

	}
	
	private void createLuceneIndex(){
		Indexer indexer = new Indexer(indexDirectory,dataDirectory);
		//Create IndexWriter
		indexer.createIndexWriter();
		try {
			//Index data
			indexer.indexData();
		} catch (FileNotFoundException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	
	
	
	private void createIndexSearcher() throws CorruptIndexException, IOException{
		/* Create instance of IndexSearcher 
		 */
		indexSearcher = new IndexSearcher(indexDirectory);		
	}
	
	private void showSearchResults(Query query ){
		
		try{
			/* First parameter is the query to be executed and 
			   second parameter indicates the no of search results to fetch
			 */
			TopDocs topDocs = indexSearcher.search(query,20);	
			System.out.println("Total hits " topDocs.totalHits);
			
			// Get an array of references to matched documents
			ScoreDoc[] scoreDosArray = topDocs.scoreDocs;	
			for(ScoreDoc scoredoc: scoreDosArray){
				//Retrieve the matched document and show relevant details
				Document doc = indexSearcher.doc(scoredoc.doc);
				System.out.println("\nSender: " doc.getField("sender").stringValue());
				System.out.println("Subject: " doc.getField("subject").stringValue());
				System.out.println("Email file location: " 
								doc.getField("emailDoc").stringValue());	
			}
			System.out.println("---------------------------------------------");
		}catch(IOException e){
			e.printStackTrace();
		}
		
	}
	
	/*
	 * Searches mails that contain the word "java" in subject field.
	 */
	private void termQueryExample(){
		System.out.println("TermQuery example: Search mails having the word \"java\""  
				" in the subject field");
		Term term = new Term("subject","java");
		Query query = new TermQuery(term);	    
	    showSearchResults(query);
	}
	
	/**
	 * Searches mails received between 01/06/2009 to 6/06/2009 both inclusive
	 */
	private void rangeQueryExample(){
		System.out.println("RangeQuery example: Search mails from 01/06/2009 "  
				"to 6/06/2009 both inclusive");
		Term begin = new Term("date","20090601");
	    Term end = new Term("date","20090606");
	    Query query = new RangeQuery(begin, end, true);
	    showSearchResults(query);
	}
	
	/**
	 * Searches mails having sender field prefixed by the word "job"
	 */
	private void prefixQueryExample(){
		System.out.println("PrefixQuery example: Search mails having sender field prefixed by the word 'job'");
		PrefixQuery query = new PrefixQuery(new Term("sender","job"));
	    showSearchResults(query);
	}
	
	/**
	 * 	Searches mails that contain both "java" and "bangalore" in the subject field   
	 */
	private void booleanQueryExample(){
		System.out.println("BooleanQuery: Search mails that have both 'java' "  
				"and 'bangalore' in the subject field ");
		Query query1 = new TermQuery(new Term("subject","java"));
		Query query2 = new TermQuery(new Term("subject","bangalore"));
		BooleanQuery query = new BooleanQuery();
		query.add(query1,BooleanClause.Occur.MUST);
		query.add(query2,BooleanClause.Occur.MUST);
		showSearchResults(query);
	}
	
	/*
	 * Searches mails that contain a give phrase in the subject field.
	 */
	private void phraseQueryExample(){
		System.out.println("PhraseQuery example: Search mails that have phrase "  
				"'job opening j2ee' in the subject field.");
		PhraseQuery query = new PhraseQuery();
		query.setSlop(1);
		//Add terms of the phrases.
		query.add(new Term("subject","job"));
		query.add(new Term("subject","opening"));
		query.add(new Term("subject","j2ee"));
		
		showSearchResults(query);
	}
	
	/**
	 * Searches mails that have word 'architect' in subject field.
	 */
	private void wildCardQueryExample(){
		System.out.println("WildcardQuery: Search for 'arch*' to find emails that "  
				"have word 'architect' in subject field.");
		Query query = new WildcardQuery(new Term("subject","arch*"));
		showSearchResults(query);
	}
	
	/**
	 * Searches for emails that have word similar to 'admnistrtor' in the 
	 * subject field. Note that we have misspelled the word and looking for
	 * a word that is a close match to this.
	 */
	private void fuzzyQueryExample(){
		System.out.println("FuzzyQuery: Search for emails that have word similar " 
		    "to 'admnistrtor' in the subject field. Note we have misspelled administrator here.");
		Query query = new FuzzyQuery(new Term("subject", "admnistrtor"));
		 showSearchResults(query);
	}
	
	/**
	 * Shows how to use QueryParser
	 */
	private void queryParserExample(){
		//first argument is the default field for query terms
		System.out.println("QueryParser: Searches for mails that have given user"  
				" entered query expression in the subject field.");
		QueryParser queryParser = new QueryParser("subject",new StandardAnalyzer());
		try {
			/* Searches for emails that contain the words 'job openings'
			 *  and '.net' and 'pune'
			 */
			Query query = queryParser.parse("job openings AND .net AND pune");
			showSearchResults(query);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	
	private void queryResultsSortingExample(){
		Query query = new TermQuery(new Term("java"));
		//Filter filter = new TermsFilter();
		//TopDocs topDocs = indexSearcher.search(query, n)
	}
	
	/**
	 * Delete all the mails from the index that were received in May 2009.
	 */
	private void deletDocumentFromIndex(){
		try {
			
			//Check how many emails received in May 2009
			Query query = new WildcardQuery(new Term("month","05"));
			System.out.println("---------------------------------------------");
			System.out.println("\nSearching for mails that were received in May");
			showSearchResults(query);			

			IndexReader indexReader = IndexReader.open(indexDirectory);
			indexReader.deleteDocuments(new Term("month","05"));
			//close associate index files and save deletions to disk
			indexReader.close();	
			
			createIndexSearcher();
			System.out.println("After deleting mails received in May, "  
					"searching for mails that were received in May");
			showSearchResults(query);
			
			
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/*
	 * Shows the result of boosting fields.
	 */
	void fieldBoostFactorExample(){
		/*Searches mails that have word 'job' in their subject field, giving
		  importance to mails having word 'pune' See Indexer.java line 102
		 */
		System.out.println("Boosting fields and documents: Searches mails that"  
				" have 'job' in their subject field, giving more importance to "  
				" mails having 'pune' in their subject field");
		WildcardQuery query = new WildcardQuery(new Term("subject","job*"));
		showSearchResults(query);
	}
	
	/**
	 * Shows how to sort the results
	 */
	
	void sortBySenderExample(){
		
		/* Search mails having the word 'job' in subject and return results
		   sorted by sender's email in descending order.
		 */
		SortField sortField = new SortField("sender",true);	
		Sort sortBySender = new Sort(sortField);
		WildcardQuery query = new WildcardQuery(new Term("subject","job*"));
		
		try {
			System.out.println("Sorting results: Search mails having the word 'job' in subject");
			System.out.println("--- Showing results sorted by relevance");
			TopDocs topDocs = indexSearcher.search(query,20);
			printResults(topDocs);
			//Pass the sort criteria to search
			System.out.println("--- Sorting by sender names in descending order");
			topDocs = indexSearcher.search(query,null,20,sortBySender);
			printResults(topDocs);
			System.out.println("--- Sorting by the document index order");
			topDocs = indexSearcher.search(query,null,20,Sort.INDEXORDER);
			printResults(topDocs);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void printResults(TopDocs topDocs)
			throws CorruptIndexException, IOException {
		for(ScoreDoc scoredoc: topDocs.scoreDocs){
			//Retrieve the matched document and show relevant details
			Document doc = indexSearcher.doc(scoredoc.doc);
			System.out.println("Sender: " doc.getField("sender").stringValue());
		}
	}
	
	/*
	 * Searches for mails that have 'job' in the subject field, applies a filter
	 * to exclude mails that have sender address prefixed by word 'job' 
	 */
	
	void filterExample(){
		Term prefix = new Term("sender","jobs");
		Filter prefixFilter = new PrefixFilter(prefix);
		WildcardQuery query = new WildcardQuery(new Term("subject","job*"));
		try {
			System.out.println("Search for mails that have 'job' in the subject"  
					" field, apply a filter to exclude mails that have sender"  
					" email prefixed by 'job'");
			System.out.println("---------------------------------------------");
			System.out.println("--- Before applying prefix filter");
			TopDocs topDocs = indexSearcher.search(query,20);
			printResults(topDocs);
			System.out.println("--- After applying prefix filter");
			topDocs = indexSearcher.search(query,prefixFilter,20);
			printResults(topDocs);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
}

标签: Lucene java 搜索

实例下载地址

java lucene搜索 常用示例源码下载

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

相关文章

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警