zoukankan      html  css  js  c++  java
  • 为自己的系统搞个全文搜索 参考值:2 (转)

    在本文我又提到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就可以了。

  • 相关阅读:
    jenkins使用
    pytest+allure生成接口自动化测试报告
    charles系列
    go语言安装使用
    go语言介绍
    Nginx
    python面试题-python相关
    pyhon全栈开发学习目录
    补充【第二章】supervisor守护进程保障服务
    python全栈开发基础【补充】python中列表排序,字典排序,列表中的字典排序
  • 原文地址:https://www.cnblogs.com/flyfish/p/301725.html
Copyright © 2011-2022 走看看