lucene 初探
----索引并搜索数据库
最近在一个项目中,研究sakai中如何实现查询功能,是用lucene和nuth等相关技术来实现的,所以顺便就学习下关于LUCENEd的知识了,在这顺便整理下,供需要学习相关知识的朋友参考。
在SAKAI项目中,它实现了对PDF,WORD,HTML,XML等各种资源的检索,代码也是相当的复杂,我看了一个星期了,才刚刚有一点点头绪,不过对于整体的把握还是不是很明白,因为它用了SPRING,HIBERNATE,VM,JSF等好多技术,而我掌握的还不够成熟,所以看那么长的代码还是件比较痛苦的事情。而且,它主要是对文件系统资源的检索,而我可能要涉及的是对数据库中XML字段的检索,所以还要看ORACAL的一些英文文档,总之,还真是有些麻烦呀。好了,不抱怨了,今天实践了下如何正对数据库的普通数据建立索引并进行检索,总结一下。
1、准备工作。建数据库(cwb),建表article(article_id,article_name,article_intro),均为VARCHAR类型。 我在myeclipse里实践的,所以相关.jar文件也是需要导入的。
2、建立一个document类,为建立索引作准备。
主要代码:document类的一个重要方法。
public static Document Document(String Article_id,String Article_name,String Article_intro){
Document doc = new Document();
doc.add(Field.Keyword("Article_id", Article_id));
doc.add(Field.Text("Article_name", Article_name));
doc.add(Field.Text("Article_intro", Article_intro));
return doc;
}
这个方法很重要,Field类是索引过程中的一个核心类,Field添加的域对应于数据库中的一个字段,Keyword,Text等是不同类型的域,这些在以后再细细总结吧。
3、下一步我们要建立索引了。
在建立索引时我们需要作三个方面的工作:一,建立索引存放路径,二,从数据库中查询出需要建立索引的数据,三,将这些数据导入writer中,建立索引。
重要的代码:
1) IndexWriter writer = new IndexWriter("E:\\index", new StandardAnalyzer(), false);
2)ResultSet rs = stmt.executeQuery(
"select Article_id,Article_name,Article_intro from Article");前面关于连接数据库的代码就省略了。
3)while (rs.next()) {
writer.addDocument(Mydocument.Document(rs.getString("Article_id"), rs.getString("Article_name"),rs.getString("Article_intro")));
}
注意,在建立索引时需要捕获一些异常。
4、进行查询。这里我们可以通过一个普通的HTML页面来接收用户传递的查询短语和词。
<input size="50" type="text" name="keyword" style="font-size: 9pt">
<input type="submit" name="submit" value="搜索" style="font-size: 9pt">
很简单的代码
5、进行查询。这里有四个方面,一,获得参数;二,获得索引位置;三,检索并返回结果;四,显示结果。
1)String keyword=request.getParameter("keyword");
2)Searcher searcher = new IndexSearcher("E:\\index")。
3)Query query = QueryParser.parse(keyword, "Article_intro", new StandardAnalyzer());
Hits hits = searcher.search(query);
4)java.text.NumberFormat format = java.text.NumberFormat.getNumberInstance();
System.out.println(hits.length()+"ge Jieguo");
for (int i = 0; i < hits.length(); i++) {
Document doc = hits.doc(i);
out.println(doc.get("Article_id"));
out.println(doc.get("Article_name"));
out.println("zhunqueduwei" + format.format(hits.score(i) * 100.0) + "%");
}
注意:数据的格式化,捕获异常,以及字符串处理等。
基本上这样就可以了,在运行时,开始发现了一个问题---同一行数据,显示多条,例如:
zhunqueduwei37.5% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi zhunqueduwei31.25% 2 yanzi
后来想了下,因为索引重复建立了多次,应该在重新建立索引之前删除以前的,这样就可以避免问题,不过我还没尝试删除索引,以后做了在把心得写下来。
由于空间问题只截取了部分代码显示,最后把相关代码附在后面,供感兴趣的朋友参考。