优化IndexModifier失败

之前曾经写了一个FastIndexModifier,直接继承的Lucene的IndexModifier,使用RAMDirectory进行索引,然后flush的时候回写到
FS目录中,之前的索引一直很正常,但今天在对论坛的帖子进行索引中,发现磁盘写入总是失败,没有任何异常抛出,但是没有实际
的数据被写入磁盘,只有一个Segments。写了几个UnitTest,不论如何测试,总是不能成功。很奇怪以前为什么跑得很正常。

最后只能换回IndexModifier,通过调整MaxBufferDocs来增大IndexWriter的RAM的使用。
虽然如此,还是不满意Lucene的IndexModifier的实现,缺乏一些灵活性。明天自己重写一个类吧,其实按说很简单:

创建1个RAMDirectory的IndexWriter,addDocument时对其进行操作,打开一个IndexReader,deleteDocument时使用它对FSDirectory操作,
flush的时候,关闭IndexReader,此时新打开一个IndexWriter用于实际的fs,将RAMDirectory加入到indexs中,回写,关闭,ok。

挺简单的,当初太懒,想少写几行代码,就直接继承了IndexModifier,现在好,被搞晕了,呵呵。

updated:问题找到了,在回写的时候,顺序出现了小小的问题。必须先关闭ramWriter,否则RAMDirectory里面没有数据.代码如下:
Read more

中文分词技术小结[转自SegWord::BruceSolo]

中文分词技术属于自然语言处理技术范畴,对于一句话,人可以通过自己的知识来明白哪些是词,哪些不是词,但如何让计算机也能理解?其处理过程就是分词算法。

现有的分词算法可分为三大类:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。

1、基于字符串匹配的分词方法
这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。常用的几种机械分词方法如下:
1)正向最大匹配法(由左到右的方向);
2)逆向最大匹配法(由右到左的方向);
3)最少切分(使每一句中切出的词数最小)。

还可以将上述各种方法相互组合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245。但这种精度还远远不能满足实际的需要。实际使用的分词系统,都是把机械分词作为一种初分手段,还需通过利用各种其它的语言信息来进一步提高切分的准确率。

一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明显特征的词,以这些词作为断点,可将原字符串分为较小的串再来进机械分词,从而减少匹配的错误率。另一种方法是将分词和词类标注结合起来,利用丰富的词类信息对分词决策提供帮助,并且在标注过程中又反过来对分词结果进行检验、调整,从而极大地提高切分的准确率。

对于机械分词方法,可以建立一个一般的模型,在这方面有专业的学术论文,这里不做详细论述。
Read more

在windows下编译Php-Java-Bridge for php4/apache2

PJB可以实现java+php的无缝整合,所谓鱼翅和熊掌均可兼得。不过,官方的发布的版本中windows版本只有for php 5的,对于我来说,短期内不会迁移到php5上,于是,如何编译就成为一个棘手的问题,以前没有在windows下编译过php4,昨晚摸索了半天终于编译成功了,下面是过程:
1. download mingw.exe
(http://prdownloads.sourceforge.net/mingw/MinGW-4.1.0.exe?download) –
这是安装程序,运行并安装到默认目录c:\mingw.
install current/full version of core, compilers, utilities (不需要sources)
完成后,将c:\mingw\bin加入到windows path路径,检验:
start->run->cmd
gcc -v

2. download and run msys.exe
(http://prdownloads.sourceforge.net/mingw/MSYS-1.0.10.exe?download) –
install to c:\msys\1.0 directory
修改 c:\msys\1.0\etc\fstab ,add the following line:
c:/src /src
c:/j2sdk1.4.2_06 /java {make sure this is the path to your j2sdk} –

3. download and run msys-dtk
(http://prdownloads.sourceforge.net/mingw/msysDTK-1.0.1.exe?download)

4. download the php source (我的为4.3.11 )
and install to a directory (c:\src\php-4.3.11)

5. download the win32build.zip
(http://www.php.net/extra/win32build.zip) and install to a directory
(c:\src\win32build)
copy win32build/bin下的文件到c:/mingw/bin,否则下面的php的configure无法运行

6. 在 win32build/include创建几个空文件,为了避免#include找不到文件:
/sys/poll.h
/sys/wait.h

7. download the javabridge source (tar.bz2 版本);
解压到php-4.3.11/ext/java 目录下(原来的内容删除)

8. Update the “m4_include” paths in
ext\java\config.m4 将目录以 “ext/java/”开始; e.g.:
m4_include(ext/java/tests.m4/function_checks.m4)

9. 打开 msys window (C:\msys\1.0\msys.bat)(或双击桌面上的msys图标)
cd /src/php-4.3.11
./buildconf –force (会有一些警告,不用理会)
./configure

10. Edit the php source for the following:
in php-4.3.11/main/win95nt.h 注释下列几行代码 (add // in
front of each line):
#include
typedef unsigned int uint;
typedef unsigned long ulong;
typedef long pid_t;

in php-4.3.11/tsrm/tsrm_virtual_cwd.h 注释下列几行代码 (add
// in front of each line):
typedef unsigned short mode_t;

in php-4.3.11/tsrm/tsrm_config.w32.h 注释下列几行代码 (add //
in front of each line):
#include

10. 创建一个build.bat文件到ext/java目录中:

set BRIDGE_VERSION=3.1.7
set PHP_JAVA=
set COND_GCJ=0
set EXTENSION_NAME=JAVA
set PHP_JAVA_BIN=javaw
set EXTENSION_DIR=../..
set PHP=../..

set SYS_INCLUDE=../../../win32build/include
set SYS_INCLUDE2=c:/mingw/include
set SYS_WIN32=../../win32

set PHPTS="../../../php-4.3.11/php4ts/php4ts"
set GCC=c:/mingw/bin/mingw32-gcc.exe
sed "s*@PHP_JAVA@*%PHP_JAVA%*;s*@COND_GCJ@*%COND_GCJ%*;s*@PHP_JAVA_BIN@*%PHP_JAVA_BIN%*;s*@EXTENSION@*%EXTENSION_NAME%*;s*@BRIDGE_VERSION@*%BRIDGE_VERSION%*" <./init_cfg.c.in >./init_cfg.c
sed "s*@PHP_JAVA@*%PHP_JAVA%*;s*@COND_GCJ@*%COND_GCJ%*;s*@PHP_JAVA_BIN@*%PHP_JAVA_BIN%*;s*@EXTENSION@*%EXTENSION_NAME%*;s*@BRIDGE_VERSION@*%BRIDGE_VERSION%*" <./init_cfg.h.in >./init_cfg.h
rm *.o
%GCC% -w -I%SYS_INCLUDE% -I%SYS_INCLUDE2% -I. -I%SYS_WIN32% -I%PHP% -I%PHP%/main -I%PHP%/Zend -I%PHP%/TSRM -D"ZEND_DEBUG=0" -D"TSRM_EXPORTS" -D"LIBZEND_EXPORTS" -D"ZTS" -D"_MBCS" -DCOMPILE_DL_JAVA -DPHP_WIN32 -DZEND_WIN32 -DCFG_JAVA_SOCKET_INET -D__MINGW__ -DWIN32 -DEXTENSION_DIR=\"%EXTENSION_DIR%\" -c *.c
dllwrap --export-all-symbols -k *.o -L%PHP% -l%PHPTS% -lws2_32 -o php_java_bridge.dll

11. 在文件管理器中双击build.bat,开始编译,并生成一个php_java_bridge.dll

12. copy the php_java.dll 到其它php extensions的目录下…(in my case c:\apps\php-4.3.11\extensions

13. Edit and add to php.ini(c:/windows/php.ini):

;;start php.ini addendum
[javabridge]
extension = php_java.dll

;; log level between 0 (log off) and 4 (log debug). The default "log
;; file" is the standard output. The default level is 2.

java.log_level=3

;; If you don't have a servlet engine, double-click on JavaBridge.jar
;; to start the backend and uncomment the following option.

java.socketname=9267

;; If you have a servlet engine or an application server, deploy
;; JavaBridge.war and re-start the servlet engine or the application
;; server. Comment out the "java.socketname" option and uncomment
;; the following options.

;java.hosts="127.0.0.1:8080"
;java.servlet=On

上面是一个简单的配置,用于独立运行,适合测试,具体product环境的部署方式参考pjb的README。

14. 重起服务器,运行一个 php 文件,如果看到java extension,就说明成功了。
15. 剩下的就可以按照pjb的readme文档,修改和使用其运行方式了。
通过PJB,我在CRM中使用Lucene作为一个核心,实现复杂的全文检索和预搜索(避免一些关系数据库无法实现的瓶颈),同时使用了mq实现一些异步事件模型,php负责view,一些复杂的工作交由java
应用完成,这样开发效率达到最高。

Google发布了GWT

Google发布了GoogleWebTookit,可以用java编写ajax应用,其内含一个java-javascript的编译器,可以将java类编译为普通的html+javascript,类似Gmail,googlemaps这样。而且,GWT是基于Apache的许可,这意味着可以免费用于你的程序,包括商业应用。在GWT的FAQ中多次强调这点。
以前曾经看见过有类似的,java=〉js的compiler,不过没有像google这样系统,真是诱人。有时间希望能够研究一下,看看如何集成到php+smarty的环境中,估计难度很大。
更新:
已经有人做了类似的工作:

http://angel.hurtado.googlepages.com/tutorialgwt2