`
85600367
  • 浏览: 37640 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

lucene在时间范围内对关键字的查询和分页

阅读更多
  一般简单的全文检索只需要输入关键字,然后我们按时间倒序对结果排序。
  当数据量庞大的时候还是不够友好,所以需要加上时间范围的约束。
  本文是基于别人的例子改的,只为个人积累^_^
参考出处http://zfsn.iteye.com/blog/520363

public class SearchUtil {

	//索引所在文件夹
	private String indexDir;
	//查询起始时间
	private String sDateStr;
	//查询结束时间
	private String eDateStr;
	private RangeQuery rangeQuery;
	private Query query;
	private BooleanQuery booleanQuery;
	//时间格式化类型
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

	public Map getSearchResult(String searchType, String key, Date sDate,
			Date eDate, int start, int limit) {
		
		booleanQuery = new BooleanQuery();
		// 搜索开始时间
		Date beginTime = new Date();
		ArrayList al = new ArrayList();
		HashMap map = new HashMap();
		// 获取记录数组
		List list = new ArrayList();
		Analyzer analyzer = new IKAnalyzer();
		Searcher searcher = null;
		Directory directory = null;
		try{
		// 定义解析器
		QueryParser parser = new QueryParser(searchType, analyzer);
		indexDir = IndexUtil.getValue(IndexUtil.INDEX_ROOT2);
		//indexDir 为了测试可以直接写成绝对路径
		directory = FSDirectory.open(new File(indexDir));
		searcher = new IndexSearcher(directory);
		searcher.setSimilarity(new IKSimilarity());
		
		// 若只有结束值起始值默认为1900年1月1日
		if ((sDate == null || "".equals(sDate))
				&& (eDate != null && !"".equals(eDate))) {
			Calendar calendar = Calendar.getInstance();
			calendar.set(1900, 0, 1);
			sDate = calendar.getTime();
		}
		// 若只有起始值结束值默认为当天
		if ((sDate != null && !"".equals(sDate))
				&& (eDate == null || "".equals(eDate))) {
			eDate = new Date();
		}
		if ((sDate != null && !"".equals(sDate))
				&& (eDate != null || !"".equals(eDate))) {

			// Lucene日期转换格式不准,改用format格式
			// sDateStr=DateTools.dateToString(sDate,
			// DateTools.Resolution.MINUTE);
			// eDateStr=DateTools.dateToString(eDate,
			// DateTools.Resolution.MINUTE);

			sDateStr = sdf.format(sDate);
			eDateStr = sdf.format(eDate);

			//时间范围查询
			Term tstart = new Term("createDate", sDateStr);
			Term tend = new Term("createDate", eDateStr);
			rangeQuery = new RangeQuery(tstart, tend, true);
		}

		if (key != null && !"".equals(key)) {
			query = parser.parse(key);
		}

		//按条件进行多条件查询
		if ((sDate != null && !"".equals(sDate))
				&& (eDate != null && !"".equals(eDate)) && (key != null)
				&& !"".equals(key)) {
			booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);
			booleanQuery.add(query, BooleanClause.Occur.MUST);
		} else if ((sDate != null && !"".equals(sDate))
				&& (eDate != null && !"".equals(eDate))) {
			booleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);

		} else if (key != null && !"".equals(key)) {
			booleanQuery.add(query, BooleanClause.Occur.MUST);

		} else {
			booleanQuery.add(rangeQuery, BooleanClause.Occur.SHOULD);
			booleanQuery.add(query, BooleanClause.Occur.SHOULD);
		}

		// 索引排序条件
		 SortField[] sortfield = new SortField[] { SortField.FIELD_SCORE,
		 new SortField("createDate", SortField.STRING, true) };
		Sort sort = new Sort(sortfield);
		 TopFieldDocs docs = searcher.search(booleanQuery, null, 1, sort);
		 int totalNum = docs.totalHits;
		 docs = searcher.search(booleanQuery, null, totalNum, sort);
		ScoreDoc[] scoreDocs = docs.scoreDocs;

		//高亮设置
		SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter(
				"<FONT COLOR='RED'>", "</FONT>");
		Highlighter highlighter = new Highlighter(simpleHtmlFormatter,
				new QueryScorer(query));
		// 设置提取字符串长度
		highlighter.setTextFragmenter(new SimpleFragmenter(58));
			
			if (scoreDocs.length == 0) {
				System.out.println("没有符合条件的记录");
			} else {

				for (int i = start; i < scoreDocs.length && i < start + limit; i++) {
					
					ScoreDoc scdoc = scoreDocs[i];
					Document document = searcher.doc(scdoc.doc);

					TokenStream tokenStream = analyzer.tokenStream("",
							new StringReader(document.get("content")));
					//提取高亮显示内容
					String str = highlighter.getBestFragment(tokenStream, document
							.get("content"));
					System.out.println(str);
					System.out.println(document.getField("createDate").toString());
					al.add(str);
				}
				
				// 搜索完成时间
				Date endTime = new Date();
				// 搜索所耗时间
				long timeOfSearch = endTime.getTime() - beginTime.getTime();
				System.out.println("The time For indexsearch is " + timeOfSearch
						+ " ms");

				map.put("list", al);
				map.put("time", timeOfSearch);
				map.put("total", totalNum);
			}
		}catch (Exception e) {
			e.printStackTrace();
			
		}finally {
			if (searcher != null) {
				try {
					searcher.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (directory != null) {
				try {
					directory.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return map;
	}

	//测试方法
	public static void main(String[] args) {
		SearchUtil s = new SearchUtil();
		try {
			Date sDate = sdf.parse("20101228");
			Date eDate = sdf.parse("20101229");
			s.getSearchResult("content", "星期三", null, eDate, 0, 15);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


ps: lucene版本为2.9.3 不过3.0也是可以用的代码不需改变
分享到:
评论
1 楼 diyunpeng 2012-12-03  
参考一下。。。。

相关推荐

    Lucene建索引及查询关键字

    在Eclipse环境中运用java,Lucene建索引及查询关键字

    luceneDemo(创建索引+关键字查询)

    创建索引 一、创建词法分析器 二、创建索引存储目录 三、创建索引写入器 四、将内容存储到索引 关键字查询 一、创建索引存储目录读取器 二、创建索引搜索器 三、解析查询 四、获取结果

    android+lucene实现全文检索并高亮关键字索引库

    在Android中,由于内存和性能的限制,我们需要对Lucene进行适当的调整和优化。这通常包括在内存中存储尽可能少的数据,以及利用SQLite数据库作为临时存储。 1. **安装和集成Lucene**: 在Android项目中,我们需要...

    android+lucene实现全文检索并高亮关键字

    在Android平台上实现全文检索并高亮关键字是一项技术挑战,但通过集成Apache Lucene库,可以有效地解决这个问题。Apache Lucene是一个高性能、可扩展的信息检索库,它为开发人员提供了强大的文本搜索功能。以下是对...

    Lucene时间区间搜索

    总之,Lucene在C#中的时间区间搜索是通过构建和执行RangeQuery来实现的,这涉及到索引构建、查询解析、时间值的转换和比较等多个环节。合理地利用这些技术,可以有效地提升数据检索的效率和准确性。在实际应用中,还...

    lucene查询工具类和IndexSearcher分页查询示例

    在本文中,我们将深入探讨如何使用Lucene查询工具类和`IndexSearcher`进行分页查询,这在处理大量数据时尤其有用。Lucene是一个强大的全文搜索引擎库,它提供了高效、可扩展的文本检索功能。在Java开发环境中,...

    Lucene5学习之分页查询

    本文将深入探讨"Lucene5学习之分页查询"这一主题,结合给定的标签"源码"和"工具",我们将讨论如何在Lucene5中实现高效的分页查询,并探讨其背后的源码实现。 首先,理解分页查询的重要性是必要的。在大型数据集的...

    lucene查询结果集分页代码

    在lucene搜索分页过程中,可以有两种方式 一种是将搜索结果集直接放到session中,但是假如结果集非常大,同时又存在大并发访问的时候,很可能造成服务器的内存不足,而使服务器宕机 还有一种是每次都重新进行搜索,这样...

    lucene3.6.1文件关键字搜索代码(附加核心包)

    在标题中提到的"lucene3.6.1文件关键字搜索代码(附加核心包)"是一个基于Lucene 3.6.1版本的示例项目,主要目的是帮助初学者理解和掌握如何使用Lucene进行文件中的关键字搜索。 Lucene的主要功能包括: 1. **文本...

    Lucene5学习之Highlighte关键字高亮

    在Lucene5中,Highlighter组件为搜索结果提供了一个强大的关键字高亮机制,使得用户可以快速定位到与查询相关的重要部分。 首先,我们要理解Highlighter的基本工作原理。当用户输入查询后,搜索引擎返回匹配的文档...

    Lucene3.0增删改查和关键字高亮实例

    在这个“Lucene3.0增删改查和关键字高亮实例”项目中,我们将深入理解如何利用Lucene 3.0版本进行索引构建、文档的增删改查操作,并学习关键字高亮显示的实现方法。 首先,我们要了解**创建索引**的基本流程。在...

    Lucene5学习之Suggest关键字提示

    在信息检索领域,用户输入查询时,提供快速、准确的关键字提示能显著提升用户体验。Lucene,作为Java领域最流行的全文检索库,其5.x版本引入了Suggest组件,用于实现这种功能。本文将详细解析Lucene5中的Suggest技术...

    Lucene建立索引及查询包含“java”关键字 示例代码

    这个示例代码将向我们展示如何使用Lucene来创建一个索引,并执行一个包含"java"关键字的查询。 首先,我们需要导入必要的Lucene库,包括核心类库和其他可能需要的模块,例如分析器(Analyzer)和文档(Document)...

    lucene的排序过滤和分页.zip

    在搜索引擎和信息检索系统中,Lucene是一个非常关键的开源全文搜索引擎库,它为开发者提供了在Java应用程序中实现全文搜索功能的能力。本资料主要探讨了Lucene中的排序、过滤和分页技术,这些都是构建高效、实用的...

    对内存中Lucene查询的集合进行分页

    这篇博客文章“对内存中Lucene查询的集合进行分页”探讨的是如何在处理大量数据时,有效地对Lucene查询结果进行分页显示,以提高用户体验并减轻服务器负担。 首先,理解Lucene的基本工作原理至关重要。Lucene通过...

    Lucene.net建立索引,检索分页Demo

    在 .NET 平台上,Lucene.net 提供了与原生 Lucene 相同的强大功能,并且完全兼容 .NET Framework 和 .NET Core。 1. **文本分析(Text Analysis)** 文本分析是 Lucene 的关键部分,用于将输入的字符串转换为可...

    利用lucene实现文档关键字检索

    在这个使用案例中,我们将深入探讨如何利用Lucene实现对Word文档中的关键字检索并高亮显示结果。 首先,我们需要理解Lucene的基本工作原理。Lucene通过建立倒排索引(Inverted Index)来加速查询。倒排索引是一种...

    Lunene分页关键字高亮显示

    标题 "Lunene分页关键字高亮显示" 暗示了我们正在讨论一个与搜索引擎或数据检索相关的项目,其中涉及到了Lunene(可能是Lucene的误拼),一种广泛使用的全文搜索引擎库,以及如何在搜索结果中实现分页和关键字高亮。...

    lucene第一步---6.分页

    在IT行业中,Lucene是一个非常重要的全文搜索引擎库,尤其在处理大数据量的文本搜索时,它的性能和灵活性得到了广泛认可。本篇文章将带你迈出使用Lucene的第一步,重点关注如何实现分页检索,这对于构建高效、用户...

    自己写的lucene分页高亮显示代码

    这个代码虽然有一些局限性,但对于初学者来说,它是了解 Lucene 分页和高亮基础的一个良好起点。通过深入学习和改进,可以将其优化为更健壮、高效的搜索引擎应用。祝你在学习 Lucene 的道路上不断进步,新年快乐!

Global site tag (gtag.js) - Google Analytics