zoukankan      html  css  js  c++  java
  • lucene索引并搜索mysql数据库[转]

     由于对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. }    


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

    [java] view plaincopy
     
    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.         List<SearchBean> result = null;     
    42.         conn = JdbcUtil.getConnection();     
    43.         if(conn == null) {     
    44.             throw new Exception("数据库连接失败!");     
    45.         }     
    46.         String sql = "select id, username, password, type from account";     
    47.         try {     
    48.             stmt = conn.createStatement();     
    49.             rs = stmt.executeQuery(sql);     
    50.             this.createIndex(rs);   //给数据库创建索引,此处执行一次,不要每次运行都创建索引,以后数据有更新可以后台调用更新索引     
    51.             TopDocs topDocs = this.search(queryStr);     
    52.             ScoreDoc[] scoreDocs = topDocs.scoreDocs;     
    53.             result = 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.         Directory directory = null;     
    72.         IndexWriter indexWriter = null;     
    73.          
    74.         try {     
    75.             indexFile = new File(searchDir);     
    76.             if(!indexFile.exists()) {     
    77.                 indexFile.mkdir();     
    78.             }     
    79.             directory = FSDirectory.open(indexFile);     
    80.             analyzer = new IKAnalyzer();     
    81.               
    82.             indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);     
    83.             indexWriter.setMaxBufferedDocs(maxBufferedDocs);     
    84.             Document doc = null;     
    85.             while(rs.next()) {     
    86.                 doc = new Document();     
    87.                 Field id = new Field("id", String.valueOf(rs.getInt("id")), Field.Store.YES, Field.Index.NOT_ANALYZED, TermVector.NO);     
    88.                 Field username = 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.             indexFile = new File(searchDir);     
    110.             searcher = new IndexSearcher(FSDirectory.open(indexFile));       
    111.         }     
    112.         searcher.setSimilarity(new IKSimilarity());     
    113.         QueryParser parser = 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.         List<SearchBean> listBean = new ArrayList<SearchBean>();     
    128.         SearchBean bean = null;     
    129.         for(int i=0 ; i<scoreDocs.length; i++) {     
    130.             int docId = scoreDocs[i].doc;     
    131.             Document doc = searcher.doc(docId);     
    132.             bean = new SearchBean();     
    133.             bean.setId(doc.get("id"));     
    134.             bean.setUsername(doc.get("username"));     
    135.             listBean.add(bean);     
    136.         }     
    137.         return listBean;     
    138.     }  
    139.       
    140.     public static void main(String[] args) {     
    141.         SearchLogic logic = new SearchLogic();     
    142.         try {     
    143.             Long startTime = System.currentTimeMillis();     
    144.             List<SearchBean> result = logic.getResult("商家");     
    145.             int i = 0;     
    146.             for(SearchBean bean : result) {     
    147.                 if(i == 10)   
    148.                     break;     
    149.                 System.out.println("bean.name " + bean.getClass().getName() + " : bean.id " + bean.getId()+ " : bean.username " + bean.getUsername());   
    150.                 i++;     
    151.             }  
    152.               
    153.             System.out.println("searchBean.result.size : " + result.size());     
    154.             Long endTime = System.currentTimeMillis();     
    155.             System.out.println("查询所花费的时间为:" + (endTime-startTime)/1000);     
    156.         } catch (Exception e) {   
    157.             e.printStackTrace();     
    158.             System.out.println(e.getMessage());     
    159.         }     
    160.     }     
    161. }    


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

    [java] view plaincopy
     
    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的博客就无法解析中文字符串!

  • 相关阅读:
    vue router replace
    html transition 标签
    transformorigin
    动态设置class名称
    oracle中trim,ltrim,rtrim函数用法
    blob字段存储文件并读取
    分区表的本地索引竟然失效了——ORA01502
    powerdesigner使用细节
    PLS00231错误:function name may not be used in SQL
    sqlplus命令说明
  • 原文地址:https://www.cnblogs.com/fx2008/p/4107453.html
Copyright © 2011-2022 走看看