2008年10月31日

Apache solr,构建自己的全文检索搜索引擎

作者 非鱼

公司的网站的搜索一直是使用DotLucene做的,不过一直有很多问题。比如,生成索引的速度太慢,所以不能经常的去生成索引,索引里面坏的东西太多的时候,重新生成索引基本上会失败,因为索引文件被网站进程占用,所以无法删除。没有做搜索服务,而是每个页面去打开索引目录,搜索,然后关闭,导致重复的开关动作浪费极多的CPU,而且占用相当多的内存,无法释放。而且复杂一些查询(比如范围查询,时间查询,分组统计等)因为写法比较复杂,所以根本就没有去做。关键字高亮显示也因为性能和算法问题一直没有做。自己的个人网站上,搜索用的也是PyLucene,情况差不多。

最近在查找更好的搜索引擎供应商的过程中,发现了一个好东西,Apache solr,是由Apache组织基于Lucene所做的扩展应用,详细的介绍网上有不少,就不多说了,大体来说,solr是一个基于Java服务器的服务程序,就像WebService,它自己维护索引,进行查询动作,其它需要使用全文检索功能的程序通过Post和Get的方式使用这个服务,查询命令直接返回结果XML。通过在xml配置文件里面定义字段类型和字段名字,就可以让它支持任意需要的字段数量和类型,而且能够正确处理数值类型的排序和时间类型的范围查询。而且可以通过传递查询参数简单的实现分组统计和高亮显示。

不过因为它是java的,而我又没玩过Java程序,安装和配置着实是花了不少功夫,用了整整一天,把网上那么几篇说明文章看了又看,最后终于算是搞定了。因为几遍文章写的都不全,需要凑合成一篇看才行。所以在这里记一下标准的安装配置流程:(Linux上的)

安装J2SE SDK(1.6.0_10),配置PATH环境变量,加上jdk的bin目录。因为tomcat可以从java的执行路径里获取Java_Home的值,所以不需要设置这个变量。

下载Tomcat(6.0),解压,运行一下bin目录下的startup.sh,访问8080端口,能打开就没问题了。


载solr,刚刚出的solr 1.3正式版(里面的Lucene是2.3版的,不知道能不能直接换成新出的Lucene
2.4正式版,没有试),解压,将dist目录下的war文件改名为solr.war直接复制到tomcat的webapps目录。建一个存放索引目录的
目录,比如/opt/solr-tomcat/,把解压的solr下面的examples下面的solr目录复制到这里,建立一个/tomcat
/conf/Catalina/localhost/solr.xml文件,输入以下内容:

<Context docBase="/opt/tomcat/webapps/solr.war" debug="0" crossContext="true" >
   <Environment name="solr/home" type="java.lang.String" value="/opt/solr-tomcat/solr" override="true" />
</Context>

修改/opt/solr-tomcat/solr/conf/
面的两个配置文件,solrconfig.xml和schema.xml,前者是该索引服务的一些属性,比如索引文件存放的目录(默认为与conf同级的
data目录),还有缓存,分布之类的一些设置。后者是这个库的字段定义,字段类型,字段名,处理方式。基本上很容易理解,按照自己的需要把字段名改一
下。重启tomcat,访问localhost:8080/solr如果能打开,就说明安装成功了。

在解压的solr的examples目录下有个exampledocs目录,里面有些示例xml,可以用那个post.sh来把这些xml文件发到索引服务里(对应默认的schema.xml),然后就可以在solr的管理界面里进行查询测试了。

如果这一步通过了,接下来就可以搞中文了。是的,默认情况下不识别中文,只能搜英文。

修改tomcat的server.xml配置文件,在8080端口定义的后面加上URIEncoding="UTF-8",这样才能识别UTF8编码的中文输入。

solr
部分的中文处理的途径还是挺多的,可以用自带的CJKAnalyzer,也可以用庖丁分词,但是需要自己写个代理类,我是找了个做Java的朋友帮我编译
出了这个类文件。或者还有jesoft的je-analysis.jar。需要修改schema.xml里面的字段类型定义,给某个字段类型使用适合的分
词类。用庖丁的话,还需要添加一个环境变量指定它的词库的目录PAODING_DIC_HOME。重启tomcat,再往里添加中文,就可以使用中文搜索
了。效果还是相当不错的。

服务已经起来了,接下来的问题是怎么使用这个检索服务。

官方发布了对应多种语言的客户端API,对应Python语言的版本只能用solr 1.2源码里自带的那个,1.3版代码删除了这个文件。地址在

http://svn.apache.org/viewvc/lucene/solr/tags/release-1.2.0/client/python/

用起来很简单,发布文章的速度也挺快,对中文处理有点问题,需要把里面的str函数改成unicode函数就可以了。

而C#的版本则更是麻烦,这个http://www.codeplex.com/solrsharp几乎是你唯一的选择,(当然,如果你能从solr很少的资料里面看明白如何自己发POST过去,自己实现一个也不错),而下载了这个solrsharp编译以后使用的过程中出现了N多问题。

首先是UTF8编码,需要修改它的oRequest变量使用的ContentHeader,加上charset=UTF-8的声明。然后是它启动的时候需要从你的solr服务器上读取schema.xml文件来识别里面的字段定义,但是读取这个文件的链接有问题,也需要自己修改。要不是有个老外已经找到两个问题的解决办法,想破头我也想不出来。

改完以后,基本上就可以把内容POST过去了,至于取到搜索结果以后怎么用,还得好好研究研究。