基于lucene的案例开发:实时索引的检索

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44279753

http://www.llwjy.com/blogdetail/31bb705106379feaf6d31b58dd777be6.html

个人博客小站搭建成功,网址 www.llwjy.com,欢迎大家来吐槽~

在前面的博客中,我们已经介绍了IndexSearcher中的检索方法,也介绍了如何基于lucene中的NRT*类去创建实时索引,在这篇博客中我们就重点介绍下基于实时索引的检索方案。在开始介绍之前,我们首先定一下检索结果的数据结构(这样做的好处是无论是什么检索,得到的数据结构都是一样的,方便以后的处理~)

原来我长这样

检索结果的数据结构主要包括两个字段,如下:

private int count;
private List<Document> datas;

这两个字段分别代表着该检索条件下的符合条件的记录条数和本次查询到的记录数组(该记录是索引中的记录),因此检索结果类源代码如下:

/**
 * @Description:  索引搜索结果数据结构
 */
package com.lulei.lucene.index.model;

import java.util.List;

import org.apache.lucene.document.Document;

public class SearchResultBean {
	private int count;
	private List<Document> datas;

	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public List<Document> getDatas() {
		return datas;
	}
	public void setDatas(List<Document> datas) {
		this.datas = datas;
	}
}

检索原来如此简单

检索结果介绍完了,下面就看下如何基于上次博客中的实时索引去检索数据,不知还记得上篇博客中封装的getIndexSearcher()方法(如果忘记了,看下该系列的前一篇博客),这个方法提供了当前最新可用的IndexSearcher对象,索引我们再去检索的时候,直接调用该方法即可。IndexManager类实现了另类的单例模式,使用了索引名来标识IndexManager,因此我们在写检索基类的时候,需要添加一个构造方法,如下:

public NRTSearch(String indexName) {
	indexManager = IndexManager.getIndexManager(indexName);
}

在NRTSearch类中,我们主要封装4个方法:

1.public int getIndexNum(){}
2.public SearchResultBean search(Query query, int start, int end){}
3.public SearchResultBean search(Query query, int start, int end, Sort sort){}
4.public SearchResultBean search(int start, int count){}

在四个方法分别实现:

1.获取索引中的记录条数;

2.根据query查询索引,根据相关读排序,返回[start, end)记录;

3.根据query查询索引,根据指定sort排序,返回[start, end)记录;

4:从索引中的第start条开始,获取后面的count条记录(如果start + count 大于索引中的记录总条数,则从头补齐)。

这四个方法已经可以实现了80%的站内搜索功能,如果还有其他复杂的,可以根据实际情况来拓展,NRTSearch类源代码如下:

/**
 * @Description:  索引的查询操作
 */
package com.lulei.lucene.index.operation;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;

import com.lulei.lucene.index.manager.IndexManager;
import com.lulei.lucene.index.model.SearchResultBean;

public class NRTSearch {
	private IndexManager indexManager;

	/**
	 * @param indexName 索引名
	 */
	public NRTSearch(String indexName) {
		indexManager = IndexManager.getIndexManager(indexName);
	}

	/**
	 * @return
	 * @Author:lulei
	 * @Description: 索引中的记录数量
	 */
	public int getIndexNum() {
		return indexManager.getIndexNum();
	}

	/**
	 * @param query 查询字符串
	 * @param start 起始位置
	 * @param end 结束位置
	 * @author lulei
	 * @return 查询结果
	 */
	public SearchResultBean search(Query query, int start, int end) {
		start = start < 0 ? 0 : start;
		end = end < 0 ? 0 : end;
		if (indexManager == null || query == null || start >= end) {
			return null;
		}
		SearchResultBean result = new SearchResultBean();
		List<Document> datas = new ArrayList<Document>();
		result.setDatas(datas);
		IndexSearcher searcher = indexManager.getIndexSearcher();
		try {
			TopDocs docs = searcher.search(query, end);
			result.setCount(docs.totalHits);
			end = end > docs.totalHits ? docs.totalHits : end;
			for (int i = start; i < end; i++) {
				datas.add(searcher.doc(docs.scoreDocs[i].doc));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			indexManager.release(searcher);
		}
		return result;
	}

	/**
	 * @param query 查询字符串
	 * @param start 起始位置
	 * @param end 结束位置
	 * @param sort 排序条件
	 * @return 查询结果
	 */
	public SearchResultBean search(Query query, int start, int end, Sort sort) {
		start = start < 0 ? 0 : start;
		end = end < 0 ? 0 : end;
		if (indexManager == null || query == null || start >= end) {
			return null;
		}
		SearchResultBean result = new SearchResultBean();
		List<Document> datas = new ArrayList<Document>();
		result.setDatas(datas);
		IndexSearcher searcher = indexManager.getIndexSearcher();
		try {
			TopDocs docs = searcher.search(query, end, sort);
			result.setCount(docs.totalHits);
			end = end > docs.totalHits ? docs.totalHits : end;
			for (int i = start; i < end; i++) {
				datas.add(searcher.doc(docs.scoreDocs[i].doc));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			indexManager.release(searcher);
		}
		return result;
	}

	/**
	 * @param start
	 * @param count
	 * @return
	 * @Author:lulei
	 * @Description: 按序号检索
	 */
	public SearchResultBean search(int start, int count) {
		start = start < 0 ? 0 : start;
		count = count < 0 ? 0 : count;
		if (indexManager == null) {
			return null;
		}
		SearchResultBean result = new SearchResultBean();
		List<Document> datas = new ArrayList<Document>();
		result.setDatas(datas);
		IndexSearcher searcher = indexManager.getIndexSearcher();
		result.setCount(count);
		try {
			for (int i = 0; i < count; i++) {
				datas.add(searcher.doc((start + i) % getIndexNum()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			indexManager.release(searcher);
		}
		return result;
	}
}

到这里为止,NRTSearch类就介绍完毕了,之后就可以根据实际的应用来创建子类,实现一系列的查询操作,如:关键字检索、分类检索、标签检索、作者检索等等,在之后的应用中在继续介绍。

ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于 基于lucene的案例开发  请点击这里。或访问网址http://blog.csdn.net/xiaojimanman/article/category/2841877 或 http://www.llwjy.com/

时间: 2024-12-15 01:32:41

基于lucene的案例开发:实时索引的检索的相关文章

基于lucene的案例开发:实时索引管理类IndexManager

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44015983 http://www.llwjy.com/blogd.php?id=5757ce8c007754704b563dd6a47ca1ca 个人的博客小站也搭建成功,网址:www.llwjy.com/blog.php ,欢迎大家来吐槽~ 在前一篇博客中,对实时索引的实现原理做了一些简单的介绍,这里就介绍下,如何利用Lucene来实现索引的管理(Lucene中已经实现了大

基于lucene的案例开发:IndexSearcher中检索方法

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/43052829 前面我们介绍了Analyzer和Query,这篇我们就开始该系列最后一个类IndexSearcher的搜索API介绍,Lucene中重点API不止这里介绍的这一点,还有IndexWriter.Field.Highlighter等,这些就不在这一部分做介绍了,如若案例中用到的话,再做简单介绍. 查看Lucene4.3.1中IndexSearcher的API请点击这里

基于lucene的案例开发:索引文件结构

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/42836309 前面我们已经介绍了非结构数据的检索过程以及lucene的数学模型,这篇博客就主要介绍一下lucene索引的文件结构,下图是lucene生成的索引实例: lucene索引结构是层次结构,主要有以下几个层次: 索引(Index) 在lucene中,一个索引是放在一个文件夹中的,上述实例中的所有文件就组成了lucene索引 段(Segment) 一个索引中可以有很多段,

基于lucene的案例开发:索引数学模型

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/42818185 通过前一篇博客,对所以也许有了一个大致的了解,知道检索是一个怎样的过程,这篇博客就简单的介绍一下lucene实现的数学模型. 前面我们已经提到lucene实现的索引是一种反向索引,有词典和倒排表组成(实际的结构要比这个复杂很多),那索引的数学模型又是怎样的呢?在开始这个之前,还是先熟悉下几个名词.       文档(Document):上篇博客中的索引创建过程中列

基于lucene的案例开发:创建索引

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/42872711 从这篇博客开始,不论是API介绍还是后面的案例开发,都是基于 lucene4.3.1 这个版本,Lucene4.3.1 下载请点击这里, Lucene其他版本下载请点击这里,Lucene4.3.1官方API文档请点击这里. 创建索引demo 在开始介绍之前,先看一个简单的索引创建demo程序: /** *@Description: 索引创建demo */ pack

基于lucene的案例开发:实时索引的修改

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44280311 http://www.llwjy.com/blogdetail/e42fa5c3097f4964fca0fdfe7cd7a9a2.html 个人的博客小站已经上线了,网址 www.llwjy.com,欢迎大家来吐槽~ 上一篇博客已经介绍了实时索引的检索功能,这个就相当于数据的的查询功能,我们都知道数据库的增删改查是最常用的四个功能,实时索引也是一样,他也有增删改查

基于lucene的案例开发:实现实时索引基本原理

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/43982653 http://www.llwjy.com/blogd.php?id=63d4c488a2cccb5851c0498d374951c9 个人的博客小站也搭建成功,网址:www.llwjy.com/blog.php ,欢迎大家来吐槽~ 基本原理 在前面的博客中也说过,程序初始话索引文件是十分消耗系统资源的,因此要想实现实时索引就不能实时的去修改索引文件.重新加载索引文

基于lucene的案例开发:案例初识

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/43192055 首先抱歉,这几天在准备案例的整体框架设计,所以更新就断了几天,还请原谅. 案例整体介绍 在我们开始正式的案例开发介绍之前,我们先看一下整体的案例demo介绍,明白案例是做什么的. 从上图中,我们可以看出,这个案例主要是通过爬虫程序去采集纵横小说上的资源,然后将资源存储到自己的数据库中,将数据库中的需要检索的数据通过lucene建立索引文件,最后通过web服务展示数

基于lucene的案例开发:查询语句创建PackQuery

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44656141 http://www.llwjy.com/blogdetail/162e5e70516d7ddfb6df8f77e6b13a2b.html 个人博客站已经上线了,网址 www.llwjy.com~欢迎各位吐槽 ------------------------------------------------------------------------------