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

为自己的系统搞个全文搜索
 
在本文我又提到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就可以了

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏