[转]Lucene 全文检索实践
作者:baggio785
作者Blog:http://blog.youkuaiyun.com/baggio785/
本文来源:http://www.lucene.com.cn/sj.htm
Lucene
Lucene 是 Apache Jakarta 的一个子项目,是一个全文检索的搜索引擎库。其提供了简单实用的 API,通过这些 API,可以自行编写对文件(TEXT/XML/HTML等)、目录、数据库的全文检索程序。
Features:
* Very fast indexing, minimal RAM required
* Index compression to 30% of original text
* Indexes text and HTML, document classes available for XML, PDF and RTF
* Search supports phrase and Boolean queries, plus, minus and quote marks, and parentheses
* Allows single and multiple character wildcards anywhere in the search words, fuzzy search, proximity
* Will search for punctuation such as + or ?
* Field searches for title, author, etc., and date-range searching
* Supports most European languages
* Option to store and display full text of indexed documents
* Search results in relevance order
* APIs for file format conversion, languages and user interfaces
实践任务:
1) 编写 Java 程序 MyIndexer.java,使用 JDBC 取出 MySQL 数据表内容(以某一论坛数据做测试),然后通过 org.apache.lucene.index.IndexWriter 创建索引。
2) 编写 Java 程序 MySearcher.java,通过 org.apache.lucene.search.IndexSearcher 等查询索引。
3) 实现支持中文查询及检索关键字高亮显示。
4) 通过 PHP / Java Integration 实现对 MySearch.java 的调用。
5) 实现对 PHP 手册(简体中文) 的全文检索。
Lucene 全文检索实践(2)
Java 的程序基本编写完成,实现了对中文的支持。下一步是将其放到 WEB 上运行,首先想到的是使用 JSP,安装了Apache Tomcat/4.1.24,默认的发布端口是 8080。现在面临的一个问题是:Apache httpd 的端口是 80,并且我的机器对外只能通过 80 端口进行访问,如果将 Tomcat 的发布端口改成 80 的话,httpd 就没法对外了,而其上的 PHP 程序也将无法在 80 端口运行。
对于这个问题,我想到两种方案:
1、使用 PHP 直接调用 Java。需要做的工作是使用 --with-java 重新编译 PHP;
2、使用 mod_jk 做桥接的方式,将 servlet 引擎结合到 httpd 中。需要做的工作是编译 jakarta-tomcat-connectors-jk-1.2.5-src,生成 mod_jk.so 给 httpd 使用,然后按照 Howto 文档 进行 Tomcat、httpd 的配置。
对于第一个方案的尝试:使用 PHP 直接调用 Java
环境
* PHP 4.3.6 prefix=/usr
* Apache 1.3.27 prefix=/usr/local/apache
* j2sdk1.4.1_01 prefix=/usr/local/jdk
配置步骤
1) 安装 JDK,这个就不多说了,到 GOOGLE 可以搜索出这方面的大量文章。
2) 重新编译 PHP,我的 PHP 版本是 4.3.6:
cd php-4.3.6
./configure --with-java=/usr/local/jdk
make
make install
完成之后,会在 PHP 的 lib 下(我的是在 /usr/lib/php)有个 php_java.jar,同时在扩展动态库存放的目录下(我的是在 /usr/lib/php/20020429)有个 java.so 文件。到这一步需要注意一个问题,有些 PHP 版本生成的是 libphp_java.so 文件,extension 的加载只认 libphp_java.so,直接加载 java.so 可能会出现如下错误:
PHP Fatal error: Unable to load Java Library /usr/local/jdk/jre/lib/i386/libjava.so, error: libjvm.so:
cannot open shared object file: No such file or directory in /home/nio/public_html/java.php on line 2
所以如果生成的是 java.so,需要创建一个符号连接:
ln -s java.so libphp_java.so
3) 修改 Apache Service 启动文件(我的这个文件为 /etc/init.d/httpd),在这个文件中加入:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/jdk/jre/lib/i386/server:/usr/local/jdk/jre/lib/i386
正如你所看到的,我的 JDK 装在 /usr/local/jdk 目录下,如果你的不是在此目录,请做相应改动(下同)。
4) 修改 PHP 配置文件 php.ini,找到 [Java] 部分进行修改:
[Java]
java.class.path = /usr/lib/php/php_java.jar
java.home = /usr/local/jdk
;java.library =
;java.library.path =
extension_dir=/usr/lib/php/20020429/
extension=java.so
我将 java.library 及 java.library.path 都注释掉了,PHP 会自动认为 java.library=/usr/local/jdk/jre/lib/i386/libjava.so。
5) 重新启动 Apache httpd 服务:
service httpd restart
测试
测试脚本 java.php 源代码:
getProperty('java.version').'<br />';
print 'Java vendor=' . $system->getProperty('java.vendor').'<br />';
print 'OS=' . $system->getProperty('os.name') . ' ' .
$system->getProperty('os.version') . ' on ' .
$system->getProperty('os.arch') . '<br />';
?>
总结
安装配置还算简单,但是在 PHP 运行 Java 的速度感觉较慢,所以下定决心开始实践第二个方案。(待续)
Lucene 全文检索实践(3)
今天总算有些空闲时间,正好说说第二种方案:使用 mod_jk 做桥接的方式,将 servlet 引擎结合到 httpd 中。
环境
* PHP 4.3.6 prefix=/usr
* Apache 1.3.27 prefix=/usr/local/apache
* j2sdk1.4.1_01 prefix=/usr/local/jdk
* jakarta-tomcat-4.1.24 prefix=/usr/local/tomcat
* 另外需要下载 jakarta-tomcat-connectors-jk-1.2.5-src.tar.gz
配置步骤
1) 安装 JDK 与 Tomcat,这些安装步骤就不多说了。
2) 编译 jakarta-tomcat-connectors-jk-1.2.5-src,生成 mod_jk.so,并将其复制到 apache 的 modules 存放目录:
tar xzf jakarta-tomcat-connectors-jk-1.2.5-src.tar.gz
cd jakarta-tomcat-connectors-jk-1.2.5-src/jk/native
./configure --with-apxs=/usr/local/apache/bin/apxs
make
cp apache-1.3/mod_jk.so /usr/local/apache/libexec
3) 编辑 Apache 配置文件 /usr/local/apache/conf/httpd.conf,加入:
LoadModule jk_module libexec/mod_jk.so
AddModule mod_jk.c
这个 LoadModule 语句最好放在其他 LoadModule 语句后边。
同时在配置文件后边加入:
# workers.properties 文件所在路径,后边将对此文件进行讲解
JkWorkersFile /usr/local/apache/conf/workers.properties
# jk 的日志文件存放路径
JkLogFile /usr/local/apache/log/mod_jk.log
# 设置 jk 的日志级别 [debug/error/info]
JkLogLevel info
# 选择日志时间格式
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions 选项设置
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat 设置日志的请求格式
JkRequestLogFormat "%w %V %T"
# 映射 /examples/* 到 worker1,worker1 在 workers.properties 文件中定义
JkMount /examples/* worker1
4) 在 /usr/local/apache/conf/ 目录下创建 workers.properties 文件,其内容如下:
# 定义使用 ajp13 的 worker1
worker.list=worker1
# 设置 worker1 的属性(ajp13)
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker1.lbfactor=50
worker.worker1.cachesize=10
worker.worker1.cache_timeout=600
worker.worker1.socket_keepalive=1
worker.worker1.socket_timeout=300
5) 好了,启动 Tomcat,重启一下 Apache HTTPD Server,访问:http://localhost/examples/index.jsp,看看结果如何,和 http://localhost:8080/examples/index.jsp 是一样的。
提示:如果不想让别人通过 8080 端口访问到你的 Tomcat,可以将 /usr/lcoal/tomcat/conf/server.xml 配置文件中的如下代码加上注释:
<!--
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="false" redirectPort="8443"
acceptCount="100" debug="0" connectionTimeout="20000"
useURIValidationHack="false" disableUploadTimeout="true" />
-->
然后重新启动 Tomcat 即可。
总结
此方案安装配置稍微复杂些,但执行效率要比第一种方案要好很多。所以决定使用这种方案来完成我的 Lucene 全文检索实践任务。
Tomcat Service 脚本
在 Linux (我用的是 Redhat)中,如果经常需要启动/关闭 Tomcat 的话,还是创建一个 daemon 来得比较方便,创建步骤如下:
1) 在 /etc/init.d/ 目录下创建文件 tomcat,代码如下:
# chkconfig: 345 91 10
# description: Tomcat daemon.
#
# 包含函数库
. /etc/rc.d/init.d/functions