为自己的系统搞个全文搜索

    技术2022-05-11  134

    在本文我又提到lucene了,在java业界,提到全文检索,几乎没有什么人不知道它。用google搜索一下,满世界都是有关资料。具有代表性的就是车东的“基于Java的全文索引引擎Lucene简介”,我要写的也就只有最简单的三板斧,再加上支持中文的ChineseAnalyzer以及按照时间排序的搜索结果排序方法。这些都可以在其他地方找到相关资料,我只是把他们提出来,作为lucence应用中经常遇到的麻烦解决办法。去年MSN上面有个朋友跟我提到希望用lucene构建个网站的全文检索,我当时就觉得很简单,直说没问题没问题,不过他提到一个要求就是搜索结果要安装时间排序,我查阅了些资料,发现lucene并不提供用户自定义排序方式,而只能按照自己相关性算法排序。后来我在车东的weblucene项目找到了IndexOrderSearcher。解决了结果排序常规需求。IndexOrderSearcher跟一般IndexSearch使用差不多,仅仅在构建对象的时候多加一个参数IndexOrderSearcher.ORDER_BY_DOCID_DESCIndexOrderSearcher indexsearcher = new IndexOrderSearcher("/home/lucenetest/index",IndexOrderSearcher.ORDER_BY_DOCID_DESC);新版本的lucene还提供了一个MultiFieldQueryParser,可以同时检索多个字段,以前QueryParser比较麻烦。  private static ChineseAnalyzer chineseAnalyzer = new ChineseAnalyzer();  public Hits search(String queryText){        if (queryText == null){          return null; } Query query; try{   query = MultiFieldQueryParser.parse(queryText, new String[]{"title"},chineseAnalyzer);   return indexsearcher.search(query); }catch(Exception e){   return null; }}下面是构建索引,定时从数据库取出数据索引,做完记录完成时间,我是把时间写入一个txt文件。package com.test.search;

    import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.cn.*;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.*;import org.apache.lucene.index.*;

    import java.io.*;import java.sql.*;import java.util.Date;

    import com.test.db.*;import com.test.utility.*;

    /** * Title: SearchIndexer * Description: 全文索引 * Copyright:   Copyright (c) 2001 * Company: test * @author Sean * @version 1.0 */public class SearchIndexer {  private String indexPath = null;  protected Analyzer analyzer = new ChineseAnalyzer();

      public SearchIndexer(String s) {    this.indexPath = s;  }  /**   * 索引某日期以前的所有文档   * @param fromdate   * @return   */  public final void updateIndex(String fromdate) {    Connection conn = DbUtil.getCon();    IndexWriter indexWriter = null;    try {      indexWriter = getWriter(false);     //索引发布系统内部文件        PreparedStatement pstm = conn.prepareStatement(            "select title,body,creationtime from document where creationtime > '" + fromdate +            "' order by creationtime");        ResultSet rs = pstm.executeQuery();        while (rs.next()) {          String creationtime = rs.getString("creationtime");          String title = rs.getString("title");          String body = rs.getString("body");

                        if (title == null || body == null) {            continue;          }          try {            addDocsToIndex(title,body, creationtime,indexWriter);          }          catch (Exception ex) {            ex.printStackTrace();          }       }      indexWriter.optimize();    }    catch (Exception ex) {      ex.printStackTrace();    }    finally {      try {        indexWriter.close();        conn.close();      }      catch (Exception e) {        e.printStackTrace();      }    }  }  /**   * 检查索引文件是否存在   * @param s   * @return 索引是否存在   */  private boolean indexExists(String s) {    File file = new File(s + File.separator + "segments");    return file.exists();  }  /**   * 增加一组索引   * @param title   * @param body   * @param creationtime   * @param indexwriter   * @return   */  private final void addNewsToIndex(String docid, String url,String title, String body,                                      String ptime, IndexWriter indexwriter) throws      IOException {    if (indexwriter == null) {      return;    }    else {      try {        Document document = new Document();        document.add(Field.Text("title", title));        document.add(Field.Text("body", body));        document.add(new Field("creationtime", creationtime, true, true, false));        indexwriter.addDocument(document);      }      catch (Exception ex) {    ex.printStackTrace();      }      return;    }  }  /**   * 取得IndexWriter   * @param flag 是否新建索引   * @return IndexWriter   */  private IndexWriter getWriter(boolean flag) throws IOException {    String s = indexPath;    if (s == null) {      throw new IOException("索引文件路径设置错误.");    }    indexPath = s + File.separator + "search";    IndexWriter indexwriter = null;    if (flag) {      try {        indexwriter = new IndexWriter(indexPath, analyzer, true);      }      catch (Exception exception) {        System.err.println("ERROR: Failed to create a new index writer.");        exception.printStackTrace();      }    }    else {      if (indexExists(indexPath)) {        try {          indexwriter = new IndexWriter(indexPath, analyzer, false);        }        catch (Exception exception1) {          System.err.println("ERROR: Failed to open an index writer.");          exception1.printStackTrace();        }      }      else {        try {          indexwriter = new IndexWriter(indexPath, analyzer, true);        }        catch (Exception exception2) {          System.err.println("ERROR: Failed to create a new index writer.");          exception2.printStackTrace();        }      }    }    return indexwriter;  }

      public static void main(String[] args) {    String lastUpdate = "/home/lucenetest/lastUpdate.txt";    SearchIndexer searchIndexer = new SearchIndexer("/home/lucenetest/index");    //取出上次更新时间    String str = Util.readTxtFile(lastUpdate);    if(str==null || str.length()==0){      str = new java.util.Date().toString();    }    searchIndexer.updateIndex(str);    //写入当前时间    Util.writeTxtFile(lastUpdate,new java.util.Date(),false);  }}写个cmd或者sh在相应操作系统下面定时执行SearchIndexer就可以了。

     

    下载lucene包

    最新回复(0)