由于对lucene比较感兴趣,本人在网上找了点资料,终于成功地用lucene对mysql数据库进行索引创建并成功搜索,先总结如下:

    首先介绍一个jdbc工具类,用于得到Connection对象:

 

 

[java] view plaincopy

 

  1. import java.sql.Connection;     
  2. import java.sql.DriverManager;       
  3. import java.sql.SQLException;    
  4. /**     
  5. * JdbcUtil.java   
  6. * @version 1.0   
  7. * @createTime JDBC获取Connection工具类   
  8. */    
  9. public class JdbcUtil {     
  10. private static Connection conn = null;     
  11. private static final String URL = "jdbc:mysql://127.0.0.1/project?autoReconnect=true&characterEncoding=utf8";     
  12. private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";     
  13. private static final String USER_NAME = "root";     
  14. private static final String PASSWORD = "";  
  15.       
  16. public static Connection getConnection() {     
  17. try {     
  18.             Class.forName(JDBC_DRIVER);     
  19.             conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);     
  20. catch (ClassNotFoundException e) {     
  21.             e.printStackTrace();     
  22. catch (SQLException e) {     
  23.             e.printStackTrace();     
  24.         }     
  25. return conn;     
  26.     }  
  27. }    

    然后就是本文的主要内容了,对数据库信息进行索引与对索引进行搜索:

 

 

1. import java.io.File;     
2. import java.sql.Connection;     
3. import java.sql.ResultSet;     
4. import java.sql.Statement;     
5. import java.util.ArrayList;     
6. import java.util.List;     
7. import org.apache.lucene.analysis.Analyzer;     
8. import org.apache.lucene.document.Document;     
9. import org.apache.lucene.document.Field;     
10. import org.apache.lucene.document.Field.TermVector;     
11. import org.apache.lucene.index.IndexWriter;     
12. import org.apache.lucene.queryParser.QueryParser;  
13. import org.apache.lucene.search.*;  
14. import org.apache.lucene.store.Directory;     
15. import org.apache.lucene.store.FSDirectory;  
16. import org.apache.lucene.util.Version;  
17. import org.wltea.analyzer.lucene.IKAnalyzer;  
18. import org.wltea.analyzer.lucene.IKSimilarity;     
19.     
20. /**     
21. * SearchLogic.java   
22. * @version 1.0   
23. * @createTime Lucene数据库检索   
24. */    
25. public class SearchLogic {     
26. private static Connection conn = null;     
27. private static Statement stmt = null;     
28. private static  ResultSet rs = null;     
29. private String searchDir = "E:\\Test\\Index";     
30. private static File indexFile = null;     
31. private static Searcher searcher = null;     
32. private static Analyzer analyzer = null;     
33. /** 索引页面缓冲 */    
34. private int maxBufferedDocs = 500;     
35. /**   
36.     * 获取数据库数据   
37.     * @return ResultSet   
38.     * @throws Exception   
39.     */    
40. public List<SearchBean> getResult(String queryStr) throws Exception {     
41. null;     
42.         conn = JdbcUtil.getConnection();     
43. if(conn == null) {     
44. throw new Exception("数据库连接失败!");     
45.         }     
46. "select id, username, password, type from account";     
47. try {     
48.             stmt = conn.createStatement();     
49.             rs = stmt.executeQuery(sql);     
50. this.createIndex(rs);   //给数据库创建索引,此处执行一次,不要每次运行都创建索引,以后数据有更新可以后台调用更新索引     
51. this.search(queryStr);     
52.             ScoreDoc[] scoreDocs = topDocs.scoreDocs;     
53. this.addHits2List(scoreDocs);     
54. catch(Exception e) {     
55.             e.printStackTrace();     
56. throw new Exception("数据库查询sql出错! sql : " + sql);     
57. finally {     
58. if(rs != null) rs.close();     
59. if(stmt != null) stmt.close();     
60. if(conn != null) conn.close();     
61.         }              
62. return result;     
63.     }     
64.   
65. /**   
66. * 为数据库检索数据创建索引   
67. * @param rs   
68. * @throws Exception   
69. */    
70. private void createIndex(ResultSet rs) throws Exception {     
71. null;     
72. null;     
73.          
74. try {     
75. new File(searchDir);     
76. if(!indexFile.exists()) {     
77.                 indexFile.mkdir();     
78.             }     
79.             directory = FSDirectory.open(indexFile);     
80. new IKAnalyzer();     
81.               
82. new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);     
83.             indexWriter.setMaxBufferedDocs(maxBufferedDocs);     
84. null;     
85. while(rs.next()) {     
86. new Document();     
87. new Field("id", String.valueOf(rs.getInt("id")), Field.Store.YES, Field.Index.NOT_ANALYZED, TermVector.NO);     
88. new Field("username", rs.getString("username") == null ? "" : rs.getString("username"), Field.Store.YES,Field.Index.ANALYZED, TermVector.NO);     
89.                 doc.add(id);     
90.                 doc.add(username);     
91.                 indexWriter.addDocument(doc);     
92.             }     
93.                          
94.             indexWriter.optimize();     
95.             indexWriter.close();     
96. catch(Exception e) {     
97.             e.printStackTrace();     
98.         }      
99.     }     
100.    
101. /**   
102.     * 搜索索引   
103.     * @param queryStr   
104.     * @return   
105.     * @throws Exception   
106.     */    
107. private TopDocs search(String queryStr) throws Exception {            
108. if(searcher == null) {     
109. new File(searchDir);     
110. new IndexSearcher(FSDirectory.open(indexFile));       
111.         }     
112. new IKSimilarity());     
113. new QueryParser(Version.LUCENE_30,"username",new IKAnalyzer());     
114.         Query query = parser.parse(queryStr);  
115.           
116.         TopDocs topDocs = searcher.search(query, searcher.maxDoc());     
117. return topDocs;     
118.     }  
119.       
120. /**   
121.     * 返回结果并添加到List中   
122.     * @param scoreDocs   
123.     * @return   
124.     * @throws Exception   
125.     */    
126. private List<SearchBean> addHits2List(ScoreDoc[] scoreDocs ) throws Exception {     
127. new ArrayList<SearchBean>();     
128. null;     
129. for(int i=0 ; i<scoreDocs.length; i++) {     
130. int docId = scoreDocs[i].doc;     
131.             Document doc = searcher.doc(docId);     
132. new SearchBean();     
133. "id"));     
134. "username"));     
135.             listBean.add(bean);     
136.         }     
137. return listBean;     
138.     }  
139.       
140. public static void main(String[] args) {     
141. new SearchLogic();     
142. try {     
143.             Long startTime = System.currentTimeMillis();     
144. "商家");     
145. int i = 0;     
146. for(SearchBean bean : result) {     
147. if(i == 10)   
148. break;     
149. "bean.name " + bean.getClass().getName() + " : bean.id " + bean.getId()+ " : bean.username " + bean.getUsername());   
150.                 i++;     
151.             }  
152.               
153. "searchBean.result.size : " + result.size());     
154.             Long endTime = System.currentTimeMillis();     
155. "查询所花费的时间为:" + (endTime-startTime)/1000);     
156. catch (Exception e) {   
157.             e.printStackTrace();     
158.             System.out.println(e.getMessage());     
159.         }     
160.     }     
161. }

    对了上面的类还用到了一个javabean类,如下:

 

1. public class SearchBean {  
2. private String id;  
3. private String username;  
4. public String getId() {  
5. return id;  
6.     }  
7. public void setId(String id) {  
8. this.id = id;  
9.     }  
10. public String getUsername() {  
11. return username;  
12.     }  
13. public void setUsername(String username) {  
14. this.username = username;  
15.     }  
16. }

    这些代码大部分都是我在网上找到的doc文档中复制粘贴而来,本着“拿来主义”,我对这些代码修改不大,经测试,这些代码能够正常运行。

 

    写了几篇博客,对lucene的使用方式也越来越清楚,在这里也很有必要总结一下:

    使用lucene包括两个步骤,分别是索引和搜索。

    •索引过程如下:
       ◦ 创建一个IndexWriter用来写索引文件,它有几个参数,INDEX_DIR就是索引文件所存放的位置,Analyzer便是用来对文档进行词法分析和语言处理的。
       ◦ 创建一个Document代表我们要索引的文档。
       ◦ 将不同的Field加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的Field来表示。
       ◦ IndexWriter调用函数addDocument将索引写到索引文件夹中。
    •搜索过程如下:
       ◦ IndexReader将磁盘上的索引信息读入到内存,INDEX_DIR就是索引文件存放的位置。
       ◦ 创建IndexSearcher准备进行搜索。
       ◦ 创建Analyer用来对查询语句进行词法分析和语言处理。
       ◦ 创建QueryParser用来对查询语句进行语法分析。
       ◦ QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。
       ◦ IndexSearcher调用search对查询语法树Query进行搜索,得到结果TopScoreDocCollector。

    对了,必须说一下,上面的例子还用到了一个新的jar包IKAnalyzer.jar包,它是一个开源的中文分词器,如果不使用这个分词器,那么将无法解析中文,比如说我的第一篇关于Lucene的博客就无法解析中文字符串!

虽功未成,亦未敢藏私,众侠诸神通尽录于此,竟成一笈,名葵花宝典,以飨后世。