这章主要介绍IndexSearcher
IndexSearcher,一个我们用来搜索IndexWriter创建的索引的命令行程序。(记住我们的Seacher只是用来示范Lucene的搜索API的用法。你的搜索程序也可以是网页或带有GUI的桌面程序或EJB等形式。)
一下代码是从网上剪切过来的,可能有错误,但是原理都是一样的,明白了原理,什么都简单。稍后我会将我自己写的几个测试代码贴上去,可以 关注下后面的文字
MyIndexSearcher对IndexSearcher的创建和回收:
public class MyIndexSearcher {
private static IndexSearcher indexSearcher;
private static IndexReader indexReader;
private static ArrayList<Thread> threadList = new ArrayList<Thread>();
private static Directory dir = null;
private MyIndexSearcher() {
}
/**
*
* @function 创建IndexSearcher对象
* @param indexFilePath 索引路径
* @return
*/
public static IndexSearcher getInstance(String indexFilePath) {
synchronized (threadList) {
if (indexSearcher == null) {
File indexFile = new File(indexFilePath);
try {
if (!indexFile.exists()) {
indexFile.mkdirs();
}
dir = FSDirectory.open(indexFile);
// 读取索引的indexReader
indexReader = IndexReader.open(dir);
// 创建indexSearcher
indexSearcher = new IndexSearcher(indexReader);
} catch (IOException e) {
e.printStackTrace();
} finally {
indexFile=null;
}
}
if (!threadList.contains(Thread.currentThread()))
threadList.add(Thread.currentThread());
return indexSearcher;
}
}
/**
*
* @function 关闭IndexSearcher对象
*/
public static void close() {
synchronized (threadList) {
if (threadList.contains(Thread.currentThread()))
threadList.remove(Thread.currentThread());
if (threadList.size() == 0) {
try {
if (indexReader != null) {
indexReader.close();
indexReader = null;
}
if (indexSearcher != null) {
indexSearcher.close();
indexSearcher = null;
}
if (dir != null) {
dir.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
使用IndexSearcher搜索索引
IndexSearcher用来搜索而IndexWriter用来索引:暴露几个搜索方法的索引的主要链接。你可以把IndexSearcher想象为以只读方式打开索引的一个类。它提供几个搜索方法,其中一些在抽象基类IndexSearcher中实现;最简单的接受单个Query对象做为参数并返回一个Hits对象。
/**
*
* @function 查询所有资源
* @param searchParam
* 查询内容关键字
* @param pageNum 页码
* @param pageSize 每页显示大小
* @return
*/
public static List<SearchBean> getSearchBeanAll(String searchParam,
int pageNum, int pageSize) throws Exception {
// 庖丁解牛分词器
Analyzer analyzer = new PaodingAnalyzer();
// 对用户的输入进行查询
searcher = MyIndexSearcher.getInstance(FILE_PATH
+ ConfigurationManager.getInstance().getPropertiesValue(
"common.properties", "AllIndexFilePath") + "/index");
// 对用户的输入进行查询
Query query = MultiFieldQueryParser.parse(Version.LUCENE_CURRENT,
searchParam, new String[] { "title", "content", "url",
"keyword", "time" }, new BooleanClause.Occur[] {
BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD,
BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD,
BooleanClause.Occur.SHOULD }, analyzer);
BooleanQuery bQuery = new BooleanQuery();
bQuery.add(query, BooleanClause.Occur.MUST);
// 根据字段进行排序,得到查询结果
SortField sortField1 = new SortField("time", SortField.STRING, true);// false代表升序,TRUE代表降序
SortField sortField2 = new SortField("keyword", SortField.SCORE, false);
SortField sortField3 = new SortField("title", SortField.SCORE, false);
TopDocs topDocs = searcher.search(bQuery, null, 100000, new Sort(
sortField3, sortField2, sortField1));
List<SearchBean> list = getSearchResult(analyzer, topDocs, bQuery,
searchParam, pageNum, pageSize);
// for (SearchBean searchBean : list) {
// System.out.println(searchBean.toString());
// }
return list;
}
/**
*
* @function 得到查询结果
* @param analyzer 分词器
* @param topDocs 搜索文档
* @param query 搜索对象
* @param searchParam 搜索内容关键字
* @param pageNum 页码
* @param pageSize 页显示数
* @return
*/
public static List<SearchBean> getSearchResult(Analyzer analyzer,
TopDocs topDocs, Query query, String searchParam, int pageNum,
int pageSize) throws Exception {
FastVectorHighlighter highlighter = getHighlighter();
FieldQuery fieldQuery = highlighter.getFieldQuery(query);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
// 查询结果数量
num = topDocs.totalHits;
// 创建list,将结果保存其中,以便在jsp页面中进行显示
List<SearchBean> list = new ArrayList<SearchBean>();
// 模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果
int end = 0;
int begin = 0;
begin = pageSize * (pageNum - 1);
if (begin > num) {
begin = begin - pageSize + num % pageSize;
}
if (pageNum * pageSize > num) {
end = num;
} else
end = pageNum * pageSize;
// System.out.println(num + "/" + begin + "/" + end);
try {
for (int i = begin; i < end; i++) {
String bestFragmentTitle = highlighter.getBestFragment(
fieldQuery, searcher.getIndexReader(),
scoreDocs[i].doc, "title", 50);
String bestFragmentContent = highlighter.getBestFragment(
fieldQuery, searcher.getIndexReader(),
scoreDocs[i].doc, "content", 100);
String bestFragmentKeyword = highlighter.getBestFragment(
fieldQuery, searcher.getIndexReader(),
scoreDocs[i].doc, "keyword", 100);
String bestFragmentTime = highlighter.getBestFragment(
fieldQuery, searcher.getIndexReader(),
scoreDocs[i].doc, "time", 100);
Document doc = searcher.doc(scoreDocs[i].doc);
// 取得该条索引文档
SearchBean sb = new SearchBean();
String id = doc.get("id");
String title = doc.get("title");
String content = doc.get("content");
String url = doc.get("url");
String keyword = doc.get("keyword");
String time = doc.get("time");
String author = doc.get("author");
String module = doc.get("module");
String type = doc.get("type");
sb.setId(id);
sb.setTitle((bestFragmentTitle != null && bestFragmentTitle != "") ? bestFragmentTitle: title);
sb.setContent((bestFragmentContent != null && bestFragmentContent != "") ? bestFragmentContent: content);
sb.setUrl(url);
sb.setKeyword((bestFragmentKeyword != null && bestFragmentKeyword != "") ? bestFragmentKeyword: keyword);
sb.setTime((bestFragmentTime != null && bestFragmentTime != "") ? bestFragmentTime: time);
sb.setAuthor(author);
sb.setModule(module);
sb.setType(type);
list.add(sb);
}
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
} finally {
MyIndexSearcher.close();
}
return list;
}
分享到:
相关推荐
以下是对Lucene常用功能的详细介绍: 1. **创建索引** 创建索引是Lucene工作的第一步。通过`Directory`接口,如`FSDirectory`,Lucene可以读写文件系统中的索引。`IndexWriter`类负责实际的索引构建过程,它允许...
**Lucene常用Demo详解** Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。它提供了文本分析、索引构建、搜索功能的核心工具,是Java开发者在项目中实现全文检索的重要利器。本篇文章将深入探讨...
1. **Analyzer**: 分析器是Lucene的核心组件之一,负责将输入文本拆分成一系列可搜索的术语(tokens)。例如,`StandardAnalyzer` 是一个常用的分析器,它按照英文语法规则进行分词。初学者应了解如何根据需求选择或...
4. **查询构造**:Lucene使用`QueryParser`类解析用户的查询字符串,生成相应的查询对象。此外,还可以手动构造复杂的查询,如布尔查询、短语查询、范围查询等,通过`BooleanQuery`, `TermQuery`, `PhraseQuery`等类...
- **作用**:提供了一些常用的工具类和常量类的支持。 #### 三、索引文件格式 Lucene使用多种文件格式来存储索引信息: - **fnm**:包含Document中所有Field的名称。 - **fdt** 和 **fdx**:.fdt文件用于存储具有...
- `lucene-3.5.0.tgz`: 这是一个归档文件,使用tgz格式,解压后会得到Lucene 3.5.0版本的源代码。源代码包含了所有类、接口、方法和注释,是学习Lucene内部机制的关键。 4. **关键类和接口**: - `IndexWriter`: ...
- 执行查询:使用 `IndexSearcher` 对象执行查询,返回匹配的文档集合。 - 获取结果:从搜索结果中获取文档,通常按相关性排序。 ### 3. IK 分词器 IK 分词器是 Lucene 在中文环境下的常用分词工具,它能有效地...
4. **查询索引**:使用`IndexSearcher`和`QueryParser`构建查询,指定使用哪个分词器进行查询分析。 5. **执行查询**:调用`IndexSearcher`的`search`方法,获取匹配的文档结果。 在`lucene-test-master`这个压缩包...
3. **索引(Indexing)**:索引是Lucene的核心功能之一,它将文本数据转化为可供快速检索的结构。索引过程涉及构建倒排索引(Inverted Index),其中每个词元都指向包含该词元的文档列表。 4. **查询处理(Query ...
在Lucene 4.0中,我们需要创建一个`Directory`对象来存储索引,常用的是`FSDirectory`,它将索引存储在文件系统中。接着,我们使用`IndexWriter`类,设定好分词器(Analyzer)和写入参数,然后逐个读取文档,调用`...
4. 查询解析器(QueryParser):将用户输入的查询字符串转化为Lucene能够理解的查询对象。`StandardQueryParser`是常见的查询解析器。 三、Lucene实战应用 1. 创建索引:首先,我们需要创建一个`Directory`对象来...
2. **搜索索引**: 使用`IndexSearcher`来执行查询,`QueryParser`用于将用户输入转化为查询对象。 3. **结果排序与展示**: 结果集可以通过`TopDocs`获取,根据评分排序,然后逐个展示。 **应用实例** Lucene广泛...
代码中使用了`IndexWriter`、`StandardAnalyzer`和`Field`等关键类,通过创建`Document`对象并将字段添加其中,最终将文档写入索引。这不仅是Lucene编程的基本模式,也是理解全文检索技术的关键。 总之,“Lucene...
工具类对IndexWriter,IndexReader,IndexSearcher,Analyzer,QueryParser等Lucene这些常用操作对象的获取进行了封装,其中IndexWriter采用了单例模式,确保始终只有一个对象实例,因为Lucene限制了索引写操作是阻塞的...
- **执行搜索**:`IndexSearcher`负责执行查询,返回`Hits`对象,其中包含了匹配的所有文档信息。 - **结果解析**:遍历`Hits`,获取每个文档的ID、字段值及评分,用于展示或进一步处理。 #### 四、多字段搜索 多...
`IndexWriter` 是 Lucene 中的核心类之一,用于创建或更新索引。它提供了添加文档、删除文档、优化索引等操作的功能。 **1.1.2 Directory** `Directory` 在 Lucene 中代表了存储索引的地方,可以是硬盘上的文件...
- **StandardAnalyzer**:提供了较为复杂的分词机制,是最常用的分析器之一。 ##### 2. `document` 此模块定义了文档的数据结构,主要包括: - **Document**:表示一个文档,由多个Field组成。 - **Field**:表示...
**Lucene组件详解** Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护。它为Java开发者提供了强大的文本搜索功能,同时也被广泛应用于其他编程语言,如.NET平台的Lucene.Net。Lucene的核心特性包括...
Lucene是一个高性能、全文本搜索库,它提供了强大的信息检索功能,而布尔搜索是其中一种常用且灵活的搜索方式,允许用户通过逻辑运算符(如AND、OR、NOT等)来组合多个查询条件,以精确地控制搜索结果。 描述部分...
在这个搜索实例中,我们将探讨 Lucene 的基本使用和核心概念。 **一、Lucene 的基本架构** Lucene 的核心组件包括索引(Index)、文档(Document)、字段(Field)和查询(Query)。首先,我们需要将数据转化为 ...