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

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

下载lucene包 http://www.junjing.net/bak/lucene_cn.jar
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值