该配置类中提供了是否开启SPHINX查询(Enable),以及MYSQL数据库链接,以及SPHINX服务端的地址端口信息等。
下面介绍一下Sphinx的客户端代码(C#)实现,该代码被放到了Discuz.EntLib这个项目中(位于SphinxClient\),而该项目是一个基于GNU的开源项目,其类"SphinxClient"实现了构造方法和相应访问SPHINX服务端守护进程的方法,如下:
这些方法的名称和参数信息与SPHINX开放的API是对应的,而相应的SPHINX文档可以从官方下载,这里只提供一个中文文档的下载地址,也就是CORESEEK的文档链接, 如下:
http://www.coreseek.cn/uploads/pdf/sphinx_doc_zhcn_0.9.pdf
这份手册中介绍了大部分API方法的使用和示例,是目前为止网上找到最全的中文文档了。
有了客户端,我们还要在已有的搜索代码中植入SPHINX查询逻辑代码。
在原来的产品中,搜索功能是使用SQLSERVER全文检索的方法提供的,其原理是:
使用SQLSERVER全文检索方法查询帖子分表(dnt_posts,表结构如下图所示)的MESSAGE字段:
而该字段是Text类型,所以在一次性查询出所有记录的pid字段后,以distinct方法过滤其中记录重复的tid信息,最终会返回tid字段并将其放入到数据库中,相应SQL语句构造方法参照如下(Discuz.Data.SqlServer/GlobalManage.cs):
如果上述的构造方法所拼接出的SQL语句被顺利执行后,就会在相应的dnt_searchcaches表中生成一条记录,形如:
注:<ForumTopics>表示其是论坛搜索的结果(因为产品中同时也提供了空间相册搜索功能,所以这样加以标识).
而dnt_searchcacheds数据字典如下(上面的ForumTopics对应表中的tids字段:text类型 ):
然后根据这些tid记录,按分页的大小一次获取其中一段数据(比如头10条:1,5,6,10,11,12,13,2,26,25),然后再用这段tid集合作为where条件 放到类似下面的查询语句中运行,就会获取相应的主题列表了(查询结果以主题列表而不是帖子列表方式呈现,这也是为什么要在GetSearchPostContentSQL中进行distinct的原因,因为一个主题可以有多个帖子,即1:n):
select * from dnt_topics where tid in (tid集合)
原理清楚之后,下面就是加入SPHINX查询逻辑了。因为SPHINX对全文索引进行查询时,会返回相应的documemntId,相应对帖子分表中的pid字段,所以只要将逻辑代码放到GetSearchPostContentSQL中就可以了,这里使用了配置文件开关的方式来标识是否执行SPHINX查询,如下:
通过上述代码,可以看出GetSphinxSqlService()这个方法就是提供SPHINX查询和数据服务的接口,该接口定义如下:
设计这个接口的目的首先是解除Discuz.EntLib.dll与其它DLL文件的互相依赖。第二就是为了当本机用户发表或更新帖子信息时,会调用这个接口的中的相应方法来创建(CreatePost)或更新(UpdatePost)mysql数据库中的相应帖子记录,以确保sphinx获取索引数据的有效性。
可以通过反射的方法实例化该接口对象以便访问其中的方法,如下(GlobalManage.cs):
而在Discuz.EntLib中提供了该接口的MYSQL类型数据库实现方法(Discuz.EntLib\SphinxClient\SphinxSqlService.cs),如下:
上面方法中的GetSearchPostContentSQL即是SPHINX查询对象的构造和执行过程了,大家可以参照SPHINX的官方文档或之前所说的那个中文文档来查询对应的语句语法。如果该方法执行正确,就会获取一个SQL语句,该语句与SQLSERVER进行全文检索时所调用的方法返回的SQL语句结果相同。
不过上面代码中的这段代码要在这里解释一下,因为它与后面所讲述的“增量索引”是相互对应的:
上面代码是执行查询时所使用的索引名称和关键字绑定,因为考虑到创建大数据量表索引时的时间会相对较长,所以这里引入了增量索引,也就是主索引中存储的是整个数据表中的索引信息(某时间段之前),而增量索引只保存指定条件(会在下文中说明)的"新记录(某时间段之后)"信息。我们可以让“创建主索引”的工作在一天中服务器最闲的时候来生成(比如凌晨4-5点钟),而增量索引每几分钟(甚至一分钟)生成一次。这样当查询时我们同时指定这两个索引来能实现“准实时”的查询效果了。
除了在搜索时调用了该服务接口的相应方法,再有就是在创建或更新帖子信息时也调用了相应方法,比如创建帖子时(Discuz.Forum\Posts.cs):
和更新帖子时:
到这时,架构中的Discuz!NT客户端部分甚本上就介绍完了。下一篇文章中将会介绍在服务器如果安装,配置SPHINX以及定时生成主和增量索引等工作。
在前文中,介绍了Discuz!NT引入SPHINX的背景和相应的客户端的C#代码架构实现。今天这篇文章将会介绍如果在LINUX环境下安装配置SPHINX中文搜索工具,也就是服务器配置方案.
目前在网络上可以找到的SPHINX中文插件主要有两个:
1.coreseek: http://www.coreseek.cn/
2.sfc: http://code.google.com/p/sphinx-for-chinese/
其中的coreseek是目前对Discuz(PHP版)支持做的比较好的插件,它提供了相应的工具和源码包来尽可能简化sphinx的安装和配置。大家可从网上找到很多相关信息。
今天本文要说的是使用sfc来安装配置sphinx,呵呵:)
linux环境:centos 5.4 (需要安装gcc编译器来编译SPHINX源代码)
因为SPHINX要访问MYSQL数据库,所以如果机器上没有安装MYSQL,可以使用下面命令进行安装:
下面开始安装SPHINX(sfc 插件):
到这里,基本就是完成了SPHINX的下载安装过程。
下面开始下载中文字典文档:
这样就从xdict_1.1.txt文件生了xdict词典。
因为要在SPHINX中使用增量索引,因为参照官方文档中提供的思路,在指定的MYSQL数据库中创建增量统计表:
接着就是创建Sphinx主索引文件、增量索引文件存放目录:
然后编辑usr/local/sphinx/etc/sphinx.conf文件:
内容如下:
其中的searchd节点下listen对应的是就服务器SPHINX守护进程的地址和端口信息及其它进程配置参数(详见sphinx官方示例文档)
对应上面的配置文件,下面是sfc官方的说明:
charset_type = utf-8 #其中charst_type选择utf-8即可
chinese_dictionary = /path/to/xdict #chinese_dictionary是指定分词词典的选项,包括路径和文件名,这样中文支持就可以了
同时当chinese_dictionary和utf-8的ngram选项同时出现时,会优先使用sphinx-for-chinese的中文支持方法。如果要使用ngram方法,将chinese_dictionary选项去掉即可。
如果配置正确,就可以使用下面命令行来创建索引了:
信息显示:
查询:
信息显示:
开启守护进程:
信息显示:
之前提到,客户端会对主索引和增量索引同时进行查询,而主索引和增量索引会被做了定时任务方式进行执行。那么接下来就是做这一部分的工作:
创建两个shell脚本,分别用来创建主索引和创建增量索引。
1.创建主索引更新脚本,build_main_index.sh:
输入以下内容(双击打开):
2.赋予主索引更新脚本可执行权限:
3.每天凌晨定时重建主索引:
增加以下内容:
4.创建脚本build_delta_index.sh:
输入以下内容(双击打开):
5.赋予增量索引更新脚本可执行权限:
6.每3分钟自动重建一次搜索引擎的增量索引:
增加以下内容:
7.配置服务器开机启动时需要自动执行的命令
内容:
这样在服务端的配置工作就告一段落了。
当然,对于以前使用过Discuz!NT的用户,我们提供了一个同步工具来将已有的帖子分表同步的指定的MYSQL数据库里以便让SPHINX来访问。如下:
这样就解决了已有数据该如何被索引的问题,剩下的就是要不断的修改sphinx.conf文件以添加新的索引和增量索引了(因为我们使用了帖子分表功能,会在帖子表记录达到一定数量时创建新的分表,这样就可以保持当前所使用的帖子分表记录不会过于庞大,从而影响数据库查询效率)和在相应的sh文件中添加对新索引的定时创建命令了。
当然,SPHINX还支持分布式检索服务,不过因为眼下的架构未用到,所以就不多做说明了,大家可以去网上搜索相关信息即可。
原文链接:http://www.cnblogs.com/daizhj/archive/2010/06/30/discuznt_entlib_sphinx_two.html
BLOG: http://daizhj.cnblogs.com/
作者:daizhj,代震军
参考链接:
Sphinx中文指南 http://www.sphinxsearch.org/
sphinx_doc_zhcn_0.9-中文手册 http://www.coreseek.cn/uploads/pdf/sphinx_doc_zhcn_0.9.pdf
亿级数据的高并发通用搜索引擎架构设计 http://blog.s135.com/post/385/
sphinx-for-chinese : http://code.google.com/p/sphinx-for-chinese/
coreseek: http://www.coreseek.cn/