lucene对校园网资料的全文检索

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包。程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用。不同版本的lucene之间还是有一定的差异的。项目里我使用的是3.0.3版本,以编写的校园网资料模块为例,对lucene的一些基本原理和用法将直接在下面的源码和注释中介绍。

实现效果如下

lucene对校园网资料的全文检索_第1张图片

lucene对校园网资料的全文检索_第2张图片

1、首先导入lucene相关的jar包


2、前端搜索html及返回结果展示

search_result.jsp


					
您搜索的“${heightshow}”, 共有${allr}个结果
${fn:replace(data.title, search, heightshow)}
${fn:replace(data.content, search, heightshow)}
3、创建索引

lucene对校园网资料的全文检索_第3张图片

java代码

//path就是当前这个web应用是绝对路径 D:\apache-tomcat-7.0.27\webapps\schoolnet
		String path=request.getSession().getServletContext().getRealPath("/")+"\\Index\\";
		//lucene中的文件操作都是通过这Directory来实现的。Directory的实现类可以分为文件目录,内存目录和目录的代理类及工具类。
		//这里使用最简单的文件目录FSDirectory的子类SimpleFSDirectory
		Directory dir = new SimpleFSDirectory(new File(path));
		//判断是否已经存在索引目录,是则在原索引上追加内容,否则覆盖
		boolean exist = IndexReader.indexExists(dir);
		IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(
				Version.LUCENE_30), !exist, IndexWriter.MaxFieldLength.LIMITED);
		try {
			//根据项目实际情况,按需建立对应的索引,先查出数据
			List dataList=userService.executeQueryByPage("from Datas where dataecondtype.datafirsttype.id=1", null, 0, 1000);
			//将数据写进索引,一个document实际就是对应一条记录
			for (int i = 0; i < dataList.size(); i++) {
				//id要存储,不用索引。因为我们输入的是想搜索的内容,id对于查询暂时用不到,但id占存储空间小且后面拿对象很需要,所有要存储。
				//title(标题)、content(内容)要分词,索引,但不存储.由于他们太大了, 
				Document doc = new Document();
				//对id的检索策略:存储字段值,但不索引
				doc.add(new Field("id", dataList.get(i).getId().toString(), Field.Store.YES,
						Field.Index.NOT_ANALYZED));
				//对title的检索策略::不存储字段值,分词建索引
				doc.add(new Field("title", dataList.get(i).getTitle(), Field.Store.NO,
						Field.Index.ANALYZED));
				//对content的检索策略::不存储字段值,分词建索引
				doc.add(new Field("content", dataList.get(i).getContent(), Field.Store.NO,
						Field.Index.ANALYZED));
				writer.addDocument(doc);
			}
			writer.optimize();
			PrintWriter out = null;
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html;charset=utf-8");
			try {
				out = response.getWriter();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print("");
		} finally {
			//必须关闭资源
			writer.close();
		}

lucene对校园网资料的全文检索_第4张图片

生成对应索引文件

lucene对校园网资料的全文检索_第5张图片
4、搜索

	//获取搜索关键字
		String search=request.getParameter("search");
		int PagesSize=20;
		String pageNow=request.getParameter("searchpageNow");
		int pageNows=Integer.valueOf(pageNow);
		request.setAttribute("searchpageNow", pageNows);
		request.setAttribute("PagesSize", PagesSize);
		request.setAttribute("search", search);
		request.setAttribute("action", "searchdatas");
		//path就是当前这个web应用是绝对路径 D:\apache-tomcat-7.0.27\webapps\schoolnet
		String path=request.getSession().getServletContext().getRealPath("/")+"\\Index\\";
		File file=new File(path);
		//还没创建全文索引
		if (!file.exists()) {
			
		}else {
			//lucene中的文件操作都是通过这Directory来实现的。Directory的实现类可以分为文件目录,内存目录和目录的代理类及工具类。
			//这里使用最简单的文件目录FSDirectory的子类SimpleFSDirectory
			Directory dir = new SimpleFSDirectory(file);
			//创建dir的检索器
			Searcher searcher = new IndexSearcher(dir);
			try {
				//创建标准的分析器
				Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
				//构造一个布尔查询
				BooleanQuery bq = new BooleanQuery();
				//使用MultiFieldQueryParser,同时在索引的多个域中搜索同一个关键字。搜索策略:title或content满足条件即可。
				Query query = MultiFieldQueryParser.parse(Version.LUCENE_30, search,
							new String[]{"title","content"},new BooleanClause.Occur[]{BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD}, analyzer);
				//将query添加到布尔查询中。搜索策略:title和content必须满足条件。	
				bq.add(query, BooleanClause.Occur.MUST);
				//获取相匹配的搜索条件的前100个搜索结果
				TopDocs docs = searcher.search(bq, 100);
				//获取doc里存储的id
				List list = new ArrayList(docs.scoreDocs.length);
				ScoreDoc[] hits = docs.scoreDocs;
				for (int i = 0; i < hits.length; i++) {
					Document d = searcher.doc(hits[i].doc);
					list.add(Integer.valueOf(d.getField("id").stringValue()));
				}
				//根据id获取对应的实体
				List dataList = new ArrayList(list.size());
				for (Object id : list) {
					dataList.add((Datas)userService.findById(Datas.class,(Integer) id));
				}
				int allrows=dataList.size();
				int PageCount=(allrows-1)/PagesSize+1;
				if(pageNows<1)
				{
					pageNows=1;
				}
				if(pageNows>PageCount)
				{
					pageNows=PageCount;
				}
				request.setAttribute("datas", dataList);
				request.setAttribute("PageCount", PageCount);
				request.setAttribute("allrows", allrows);
			} finally {
				//必须关闭资源
				searcher.close();
			}
		}
运行效果

lucene对校园网资料的全文检索_第6张图片



你可能感兴趣的:(java)