[转]用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() + " " ;
                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: " ;
        
// 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 
+=   " " + ss + " &f= " + document.get( " path " ) + " '>File:  "   +  document.get( " path " ) + " " ;
        }
        
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() ".$s;
    
echo " ";

    
$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 "   ";
        
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环境下运行。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值