在本文我又提到lucene了,在java业界,提到全文检索,几乎没有什么人不知道它。 用google搜索一下,满世界都是有关资料。具有代表性的就是车东的“基于Java的全文索引引擎Lucene简介”, 我要写的也就只有最简单的三板斧,再加上支持中文的ChineseAnalyzer以及按照时间排序的搜索结果排序方法。 这些都可以在其他地方找到相关资料,我只是把他们提出来,作为lucence应用中经常遇到的麻烦解决办法。 去年MSN上面有个朋友跟我提到希望用lucene构建个网站的全文检索,我当时就觉得很简单,直说没问题没问题, 不过他提到一个要求就是搜索结果要安装时间排序,我查阅了些资料,发现lucene并不提供用户自定义排序方式, 而只能按照自己相关性算法排序。后来我在车东的weblucene项目找到了IndexOrderSearcher。 解决了结果排序常规需求。 IndexOrderSearcher跟一般IndexSearch使用差不多,仅仅在构建对象的时候多加一个参数IndexOrderSearcher.ORDER_BY_DOCID_DESC IndexOrderSearcher 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就可以了。
|