全文检索Lucene的第一次尝试
2008-06-21 16:25
274 查看
由于系统搜索速度一直不理想,今天决定用Lucene进行 索引。然后全表检索 核心代码如下
说明
1 StandardAnalyzer 支持中文,所以不用再找其它的了
2 Index方法里
最后面的这个true,是重新建立索引。 在第一运行时,必须重新所有所有。
Field.Index.UN_TOKENIZED 是不进行单词拆分 Field.Index.TOKENIZED 是进行拆分,
3 seacherWildcard 里面可以进行模糊搜索
4 seacherIndex 里面 MultiFieldQueryParser 支持多个字段的联合查询
5 我测试的结果,我的网站的11M的索引(应该算很一般的数据量,6000多个帖子),检索竟然几乎不需要时间?或者10毫秒以内。
6 l.seacherIndex("域名 AND 系统"); AND OR NOT 用在单词之间进行组合查询, + 代表 AND -代表 NOT
7 每次有新的数据时,比如发言或者回复则调用
进行索引更新,注意里面的参数是false;
就这些,第一次使用,效果很好。
package net.java2000.forum.util; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.sql.DataSource; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.Searcher; import org.apache.lucene.search.WildcardQuery; /** * * @author 赵学庆 www.java2000.net * */ public class Lucene { private static final String indexPath = "d:/index/www.java2000.net"; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // create(); Lucene l = new Lucene(); System.out.println("模糊搜索/n------------------------------"); l.seacherWildcard("域名"); System.out.println("索引搜索/n------------------------------"); l.seacherIndex("域名 AND 系统"); } public static void rebuildAll() { synchronized (indexPath) { Lucene l = new Lucene(); DataSource ds = (DataSource) Factory.getBean("dataSource"); Connection con = null; Statement stat = null; ResultSet rs = null; try { con = ds.getConnection(); stat = con.createStatement(); rs = stat.executeQuery("select id,subject,content from t_post"); if (rs != null) { l.Index(rs); } } catch (Exception ex) { ex.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (Exception ex) {} } if (stat != null) { try { stat.close(); } catch (Exception ex) {} } if (con != null) { try { con.close(); } catch (Exception ex) {} } } } } public synchronized Analyzer getAnalyzer() { return new StandardAnalyzer(); } private synchronized void Index(ResultSet rs) {// 通过结果集就可以获得数据源了 try { IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(), true); Date start = new Date(); while (rs.next()) { Document doc = new Document();// 一个文档相当与表的一条记录 doc.add(new Field("id", rs.getString("id"), Field.Store.YES, Field.Index.UN_TOKENIZED));// 字段id放的是数据库表中的id,lucene的一条记录的一个字段下的数据可以放多个值,这点与数据库表不同 doc.add(new Field("subject", rs.getString("subject"), Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("content", rs.getString("content"), Field.Store.YES, Field.Index.TOKENIZED)); writer.addDocument(doc); } writer.optimize();// 优化 writer.close();// 一定要关闭,否则不能把内存中的数据写到文件 Date end = new Date(); System.out.println("重建索引成功!!!!" + "用时" + (end.getTime() - start.getTime()) + "毫秒"); } catch (IOException e) { System.out.println(e); } catch (SQLException e) { System.out.println(e); } } public void IndexSingle(long id, String subject, String content) {// 通过结果集就可以获得数据源了 synchronized (indexPath) { try { IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(), false); Date start = new Date(); Document doc = new Document();// 一个文档相当与表的一条记录 doc.add(new Field("id", Long.toString(id), Field.Store.YES, Field.Index.UN_TOKENIZED));// 字段id放的是数据库表中的id,lucene的一条记录的一个字段下的数据可以放多个值,这点与数据库表不同 doc.add(new Field("subject", subject, Field.Store.YES, Field.Index.TOKENIZED)); doc.add(new Field("content", content, Field.Store.YES, Field.Index.TOKENIZED)); writer.addDocument(doc); // writer.optimize();// 优化 writer.close();// 一定要关闭,否则不能把内存中的数据写到文件 Date end = new Date(); System.out.println("索引建立成功!!!!" + "用时" + (end.getTime() - start.getTime()) + "毫秒"); } catch (IOException e) { System.out.println(e); } } } public Hits seacherWildcard(String queryString) {// 根据关键字搜索 Hits hits = null; try { Query query = new WildcardQuery(new Term("subject", "*" + queryString + "*"));// 模糊查询一下 Searcher searcher = new IndexSearcher(indexPath); hits = searcher.search(query); for (int i = 0; i < hits.length(); i++) { Document doc = hits.doc(i); } searcher.close(); } catch (Exception e) { System.out.print(e); } return hits; } public List seacherIndex(String queryString) {// 根据关键字搜索 System.out.println(queryString); Hits hits = null; try { IndexSearcher isearcher = new IndexSearcher(indexPath); // Parse a simple query that searches for "text": MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[]{"subject","content"},getAnalyzer()); // QueryParser parser = new QueryParser("subject", getAnalyzer()); Query query = parser.parse(queryString); hits = isearcher.search(query); List rtn = new ArrayList(); for (int i = 0; i < hits.length(); i++) { Document doc = hits.doc(i); rtn.add(Long.parseLong(doc.get("id").trim())); } isearcher.close(); return rtn; } catch (Exception e) { System.out.print(e); return null; } } }
说明
1 StandardAnalyzer 支持中文,所以不用再找其它的了
2 Index方法里
IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(), true);
最后面的这个true,是重新建立索引。 在第一运行时,必须重新所有所有。
Field.Index.UN_TOKENIZED 是不进行单词拆分 Field.Index.TOKENIZED 是进行拆分,
3 seacherWildcard 里面可以进行模糊搜索
4 seacherIndex 里面 MultiFieldQueryParser 支持多个字段的联合查询
5 我测试的结果,我的网站的11M的索引(应该算很一般的数据量,6000多个帖子),检索竟然几乎不需要时间?或者10毫秒以内。
6 l.seacherIndex("域名 AND 系统"); AND OR NOT 用在单词之间进行组合查询, + 代表 AND -代表 NOT
7 每次有新的数据时,比如发言或者回复则调用
public void IndexSingle(long id, String subject, String content)
进行索引更新,注意里面的参数是false;
IndexWriter writer = new IndexWriter(indexPath, getAnalyzer(), false);
就这些,第一次使用,效果很好。
相关文章推荐
- 全文检索-Lucene简介
- 【手把手教你全文检索】Apache Lucene初探
- 【Lucene】Apache Lucene全文检索引擎架构之入门实战1
- 【手把手教你全文检索】Apache Lucene初探 (zhuan)
- Lucene学习总结之一:全文检索的基本原理
- lucene全文检索应用示例及代码简析
- lucene全文检索初体验-lucene demo演示
- 基于Lucene/XML的站内全文检索解决方案:WebLucene
- lucene全文检索案例――0.2秒检索50万数据
- Lucene:基于Java的全文检索引擎简介
- 全文检索之lucene的优化篇--创建索引库
- 探索Lucene.Net全文检索(续)
- 搜索系统:全文检索(lucene、排序、多域搜索、高亮、分页、监听器)
- 全文检索lucene学习笔记(三)
- lucene全文检索应用示例及代码简析
- Lucene全文检索(一)
- Lucene:基于Java的全文检索引擎简介
- Lucene实践:全文检索的基本原理
- 全文检索与Lucene学习
- Lucene全文检索的基本原理