lucene对校园网资料的全文检索
Posted zz_cl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lucene对校园网资料的全文检索相关的知识,希望对你有一定的参考价值。
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包。程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用。不同版本的lucene之间还是有一定的差异的。项目里我使用的是3.0.3版本,以编写的校园网资料模块为例,对lucene的一些基本原理和用法将直接在下面的源码和注释中介绍。
实现效果如下
1、首先导入lucene相关的jar包
2、前端搜索html及返回结果展示
<form id="search-form" action="/schoolnet/other.do?flag=searchdatas&searchpageNow=1"method="post" name="searchdatas" target="blank" οnsubmit="return checksearch()">
search_result.jsp
<div class="site-nav">
<span>当前位置 : </span><a href="/schoolnet/login.do?flag=goIndexUI">首页</a>
<a href="/schoolnet/login.do?flag=goHomeUI" title="">个人主页</a>>>资料搜索
</div>
<c:if test="$action=='searchdatas' "> <div class="page-news">
<div class="content">
<div class="mes_response" id="mes_response">
<c:set var="heightshow" value="<span style='color:red'>$search</span>"></c:set>
<c:set var="allr" value="<span style='color:red'>$allrows</span>"></c:set>
<table>
<tr>
<th class="news-time">您搜索的“<span>$heightshow</span>”, 共有<span>$allr</span>个结果</div></th>
</tr>
<c:forEach var="data" items="$datas " varStatus="status">
<tr>
<td>
<c:if test="$fn:substringAfter(data.docu, '.')=='txt'"><img src="/schoolnet/images/front/txt.png" width="25px" height="25px"/></c:if>
<c:if test="$fn:substringAfter(data.docu, '.')=='pdf'"><img src="/schoolnet/images/front/pdf.gif" width="25px" height="25px"/></c:if>
<c:if test="$fn:substringAfter(data.docu, '.')=='doc'"><img src="/schoolnet/images/front/word.png" width="25px" height="25px"/></c:if>
<c:if test="$fn:substringAfter(data.docu, '.')=='ppt'"><img src="/schoolnet/images/front/ppt.png" width="25px" height="25px"/></c:if>
<c:if test="$fn:substringAfter(data.docu, '.')=='zip'"><img src="/schoolnet/images/front/zip.ico" width="25px" height="25px"/></c:if>
<c:if test="$fn:substringAfter(data.docu, '.')=='docx'"><img src="/schoolnet/images/front/word.png" width="25px" height="25px"/></c:if>
<span class="word4"><a
href="/schoolnet/datas.do?flag=godatasshowUI&datasid=$data.id &typeid=$data.datasecondtype.id"
class="xh" οnclick="readgt(this)" id=""
οnmοuseοver="this.style.color='#333';"
οnmοuseοut="this.style.color='#666';"
style="color: #000; font-weight: bold; text-decoration: none">$fn:replace(data.title, search, heightshow)</a>
</span><span style="float:right"></span><br/>
<span style="color: #555">$fn:replace(data.content, search, heightshow)</span>
</td>
</tr>
</c:forEach>
</table>
</div>
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<Datas> 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("<script>alert('创建索引成功');window.history.go(-1);</script>");
finally
//必须关闭资源
writer.close();
生成对应索引文件
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<Integer> list = new ArrayList<Integer>(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<Datas> dataList = new ArrayList<Datas>(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对校园网资料的全文检索的主要内容,如果未能解决你的问题,请参考以下文章