[转]用PHP调用Lucene包来实现全文检索

 

用PHP调用Lucene包来实现全文检索

作者:张杰
来源:http://www.lucene.com.cn/php.htm

相关链接
Lucene中国:http://www.lucene.com.cn
Lucene官方网站:http://lucene.apache.org/


由于工作需要,需要使用PHP实现对网站内大量数量进行全文检索,而且目前最流行的全文检索的搜索引擎库就是Lucene了,它是Apache Jakarta的一个子项目,并且提供了简单实用的API,用这些API,就可以对任何基本文本的数据(包括数据库)进行全文检索。

    因为PHP本身就支持调用外部Java类,所以先用Java写了一个类,这个类通过调用Lucene的API,实现了两个方法:  

*   public  String createIndex(String indexDir_path,String dataDir_path)
*   public  String searchword(String ss,String index_path) 

    其中createIndex是创建索引方法,传入了两个参数分别是indexDir_path(索引文件的目录),dataDir_path(被索引的文件目录),返回被索引的文件列表字符串,另一个是searchword,通过传入的关键字参数(ss)对索引进行检索,index_path就是索引文件的目录。返回所有检索到的文件。

    这里是源代码,很简单,大家可以参考一下:TxtFileIndexer.java  

package  TestLucene;

import  java.io.File;
import  java.io.FileReader;
import  java.io.Reader;
import  java.util.Date;

import  org.apache.lucene.analysis.Analyzer;
import  org.apache.lucene.analysis.standard.StandardAnalyzer;
import  org.apache.lucene.document.Document;
import  org.apache.lucene.document.Field;
import  org.apache.lucene.index.IndexWriter;
import  org.apache.lucene.index.Term;
import  org.apache.lucene.search.Hits;
import  org.apache.lucene.search.IndexSearcher;
import  org.apache.lucene.search.TermQuery;
import  org.apache.lucene.store.FSDirectory;

public   class  TxtFileIndexer ...{

    
public  String test() ...{
        
return   " test is ok hohoho " ;
    }

    
/** //**
     * 
@param  args
     
*/
    
public  String createIndex(String indexDir_path,String dataDir_path)  throws  Exception ...{
        String result 
=   "" ;
        File indexDir 
=   new  File(indexDir_path);
        File dataDir 
=   new  File(dataDir_path);
        Analyzer luceneAnalyzer 
=   new  StandardAnalyzer();
        File[] dataFiles 
=  dataDir.listFiles();
        IndexWriter indexWriter 
=   new  IndexWriter(indexDir,luceneAnalyzer, true );
        
long  startTime  =   new  Date().getTime();
        
for ( int  i = 0 ; i  <  dataFiles.length; i ++ ) ...{
            
if (dataFiles[i].isFile()  &&  dataFiles[i].getName().endsWith( " .html " )) ...{
                result 
+=   " Indexing file "   +  dataFiles[i].getCanonicalPath() + " <br /> " ;
                Document document 
=   new  Document();
                Reader txtReader 
=   new  FileReader(dataFiles[i]);
                document.add(Field.Text(
" path " ,dataFiles[i].getCanonicalPath()));
                document.add(Field.Text(
" contents " ,txtReader));
                indexWriter.addDocument(document);
            }
        }

        indexWriter.optimize();
        indexWriter.close();
        
long  endTime  =   new  Date().getTime();

        result 
+=   " It takes " + (endTime - startTime)
                
+   "  milliseconds to create index for the files in directory  "
                
+  dataDir.getPath();
        
return  result;
    }

    
public  String searchword(String ss,String index_path)   throws  Exception  ...{
        String queryStr 
=  ss;
        String result 
=   " Result:<br /> " ;
        
// This is the directory that hosts the Lucene index
        File indexDir  =   new  File(index_path);
        FSDirectory directory 
=  FSDirectory.getDirectory(indexDir, false );
        IndexSearcher searcher 
=   new  IndexSearcher(directory);
        
if ( ! indexDir.exists())...{
            result 
=   " The Lucene index is not exist " ;
            
return  result;
        }
        Term term 
=   new  Term( " contents " ,queryStr.toLowerCase());
        TermQuery luceneQuery 
=   new  TermQuery(term);
        Hits hits 
=  searcher.search(luceneQuery);
        
for ( int  i  =   0 ; i  <  hits.length(); i ++ )...{
            Document document 
=  hits.doc(i);
            result 
+=   " <br /><a href='getfile.php?w= " + ss + " &f= " + document.get( " path " ) + " '>File:  "   +  document.get( " path " ) + " </a> " ;
        }
        
return  result;
    }

}

 

 

    而PHP程序就调用这两个方法,实现对Lucene的调用,从而达到全文检索的目的。

    PHP的调用方法如下: 

    先创建一个我们写的TxtFileIndexer类的实例,
 
$tf   =   new  Java( ' TestLucene.TxtFileIndexer ' ); 

 

     然后就按正常PHP类的调用方法的方式进行调用,首先创建索引:  

$data_path   =   " F:/test/php_lucene/htdocs/data/manual " // 定义被索引内容的目录 
$index_path   =   " F:/test/php_lucene/htdocs/data/search " // 定义生成的索引文件存放目录 
$s   =   $tf -> createIndex( $index_path , $data_path );  // 调用Java类的方法 
print   $s // 打印返回的结果 

 

 

    这次再试试检索: 
 
$index_path   =   " F:/test/php_lucene/htdocs/data/search " // 定义生成的索引文件存放目录 
$s   =   $tf -> searchword( " here is keyword for search " , $index_path );
print   $s

 

     另外要注意Java类的路径,可以在PHP里设置

 
java_require( " F:/test/php_lucene/htdocs/lib/ " );  // 这是个例子,我的类和Lucene都放到这个目录下,这样就可以了,是不是很简单。 

 

     PHP源代码:test.php  


<? php

    
error_reporting ( 0 );

    java_require(
" F:/test/php_lucene/htdocs/lib/ " );

    
$tf   =   new  Java( ' TestLucene.TxtFileIndexer ' );
    
$s   =   $tf -> test();
    
print   " TestLucene.TxtFileIndexer->test()<br /> " . $s ;
    
echo   " <hr /> " ;

    
$data_path   =   " F:/test/php_lucene/htdocs/data/manual " ;
    
$index_path   =   " F:/test/php_lucene/htdocs/data/search " ;

    
if ( $_GET [ " action " ==   " create " ... {
        
$s   =   $tf -> createIndex( $index_path , $data_path );
        
print   $s ;
    }
else   ... {
        
echo   " <form method=get> <input type=text name=w /><input type=submit value=search /><br /> " ;
        
if ( $_GET [ " w " !=   "" ... {
            
$s   =   $tf -> searchword( $_GET [ " w " ] , $index_path );
            
print   $s ;
        }
    }
?>

 

 
    接下来我把环境配置说一下,先需要有Java SDK,是必须的,我使用的是1.4.2版的,其它版本应该也没问题。PHP5,试过PHP4,应该可以。由于PHP5带的Java扩展没调通,并且以前用过调用Java效率很低,很慢,所以使用了 Php/Java Bridge 这个项目。

    1. 下载JavaBridge URL:http://sourceforge.net/projects/php-java-bridge/ ,目前版本是php-java-bridge_3.0.8_j2ee.zip ,解包后把 

    a.JavaBridge/WEB-INF/cgi/java-x86-windows.dll
    b.JavaBridge/WEB-INF/lib/JavaBridge.jar

    复制到 c:/php/ext 目录下,并把java-x86-windows.dll 改名为 php_java.dll

    2.修改php.ini(例) 

 

extension = php_java.dll

[ Java ]
java.class.path 
=   " C:phpextJavaBridge.jar;F: estphp_lucenehtdocs "
java.java_home 
=   " C:j2sdk1.4.2_10 "
java.library.path 
=   " c:phpext;F: estphp_lucenehtdocs "  

 

 

    3.重启Apache即可。

    4.可以找一些文件进行索引,在test.php里可以修改索引文件和数据文件的路径。TxtFileIndexer.java的37行限制了只索引html后缀的文件,有需要也可以修改。 

    根据目前的情况(JavaBridge支持Linux和Freebsd),完全可以在linux或freebsd/apache2/php4/lucene/JavaBridge环境下运行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值