什么是Sphinx/Coreseek
Sphinx是一个在GPLv2下分发的全文检索引擎;Coreseek是一个可供企业使用的、基于Sphinx(可独立于Sphinx原始版本运行)的中文全文检索引擎,按照GPLv2协议发行,商业使用(例如, 嵌入到其他程序中)需要联系我们以获得商业授权。
一般而言,Sphinx是一个独立的全文搜索引擎;而Coreseek是一个支持中文的全文搜索引擎,意图为其他应用提供高速、低空间占用、高结果相关度的中文全文搜索能力。Sphinx/Coreseek可以非常容易的与SQL数据库和脚本语言集成。
当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从管道标准输入读取入特定格式的XML数据。通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS的原生支持)。在最新的版本中,用户还可以使用Python脚本作为数据源来获取任何已知世界和未知世界的数据,这极大的扩展了数据源的来源。
搜索API支持PHP、Python、Perl、Rudy和Java,并且也可以用作MySQL存储引擎。搜索API非常简单,可以在若干个小时之内移植到新的语言上。
Sphinx 是SQL PhraseIndex的缩写,但不幸的和CMU的Sphinx项目重名。
Coreseek http://www.coreseek.cn 为Sphinx在中国地区的用户提供支持服务.
Sphinx http://sphinxsearch.com/
Sphinx/Coreseek 的特性
高速的建立索引(在当代CPU上,峰值性能可达到10MB/秒);
高性能的搜索(在2 �C 4GB 的文本数据上,平均每次检索响应时间小于0.1秒);
可处理海量数据(目前已知可以处理超过100GB的文本数据, 在单一CPU的系统上可处理100 M 文档);
提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;
支持分布式搜索;
提供文档片段(摘要以及高亮)生成功能;
可作为MySQL的存储引擎提供搜索服务;
支持布尔、短语、词语相似度等多种检索模式;
文档支持多个全文检索字段(缺省配置下,最大不超过32个);
文档支持多个额外的属性信息(例如:分组信息,时间戳等);
停止词查询;
支持单一字节编码和UTF-8编码,以及对GBK和BIG5的完善支持;
支持英语、俄语词词干化和Soundex,以便进行词形学处理;
原生的MySQL支持(同时支持MyISAM 和InnoDB );
原生的PostgreSQL支持;
支持直接模拟为MySQL服务端运行;
支持MMSeg分词引擎,用户可自定义词典;
Python数据源支持,得以获取任何已知世界和未知世界的数据.
目前,Sphinx/Coreseek的发布包包括如下软件:
indexer: 用于创建全文索引;
search: 一个简单的命令行(CLI) 的测试程序,用于测试全文索引;
searchd: 一个守护进程,其他软件可以通过这个守护进程进行全文检索;
sphinxapi: 一系列searchd 的客户端API 库,用于流行的Web脚本开发语言(PHP, Python, Perl, Ruby, Java).
spelldump: 一个简单的命令行工具,用于从 ispell 或 MySpell (OpenOffice内置绑定) 格式的字典中提取词条。当使用 wordforms 时可用这些词条对索引进行定制.
indextool: 工具程序,用来转储关于索引的多项调试信息。此工具是从版本Coreseek 3.1(Sphinx 0.9.9-rc2)开始加入的。
mmseg: 工具程序和库,Coreseek用于提供中文分词和词典处理。
安装前准备环境
yum install make gcc g++ gcc-c++ libtool make mysql-devel libxml2-devel expat-devel
官网参考地址:http://www.coreseek.cn/products/products-install/install_on_bsd_linux/RHEL5-5/
来到官网http://www.coreseek.com/下载Coreseek 3.2.14稳定版,解压进入目录。
# tar xf coreseek-3.2.14.tar.gz
# cd coreseek-3.2.14
配置语言支持中文
# export LANG="zh_CN.UTF-8"
# export LC_ALL="zh_CN.UTF-8"
# cat testpack/var/test/test.xml
安装coreseek开发的mmseg,为coreseek提供中文分词功能
# cd mmseg-3.2.14/
# ./bootstrap
# ./configure --prefix=/usr/local/mmseg3
# make && make install
中文分词测试
# /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc src/t1.txt
中文/x 分/x 词/x 测试/x
中国人/x 上海市/x
Word Splite took: 0 ms.
安装coreseek
# cd csft-3.2.14/
# sh buildconf.sh
./configure --prefix=/alidata/server/sphinx/coreseek --without-python --without-unixodbc --with-mmseg --with-mmseg-includes=/alidata/server/sphinx/mmseg3/include/mmseg --with-mmseg-libs=/alidata/server/sphinx/mmseg3/lib/ --with-mysql=/alidata/server/mysql --with-mysql-includes=/alidata/server/mysql/include/
# make && make install
测试是否可以正常运行
# /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx-min.conf.dist
csft-4.0版显示:ERROR: nothing to do.
coreseek中文全文检索测试
# cd testpack/
# /usr/local/coreseek/bin/indexer -c etc/csft.conf
索引全部数据
# /usr/local/coreseek/bin/indexer -c etc/csft.conf -all
索引指定数据
# /usr/local/coreseek/bin/indexer -c etc/csft.conf xml
测试搜索
# /usr/local/coreseek/bin/search -c etc/csft.conf
测试搜索关键词
# /usr/local/coreseek/bin/search -c etc/csft.conf -a hello欢迎来到北京清华大学
开启搜索服务
# /usr/local/coreseek/bin/searchd -c etc/csft.conf
# 如要已启动服务,要更新索引,请使用 /usr/local/coreseek/bin/indexer-c etc/csft.conf --all --rotate
# 如要停止搜索服务,请使用 /usr/local/coreseek/bin/searchd-c etc/csft.conf --stop
然后,请参考csft-3.2.14下api目录中的相关文件,使用PHP、Python、Ruby、Java来测试搜索服务;也可以前往< ahref="/products-install/step_by_step/">搜索服务建立三步曲,查看第三步使用PHP测试。
通过以上步骤,coreseek已经安装测试完成,可以提供正常的xml数据源索引以及提供对应的搜索服务了,下一步工作,请查看手册,准备好mysql数据信息,以及进行mysql数据源的测试,并在您的应用中调用搜索服务;mysql数据源的配置可参考testpack/etc/csft_mysql.conf文件
官方文档地址:http://www.coreseek.cn/docs/coreseek_3.2-sphinx_0.9.9.html
快速安装地址:http://www.coreseek.cn/product_install/install_on_bsd_linux/#mysql
在实现以上功能之后,即可开始下面的实验。
LAMP+Coreseek+sphinx构建中文检索引擎
安装好LAMP环境,并将它们启动(略),在前面的文章中都有讲到。
1、 先给数据库插入一些数据,用于测试,在解压coreseek源码包后可以在/coreseek-4.1-beta/testpack/var/test/找到.sql的数据库脚本文件,导入数据库即可。
2、 安装PHP的sphinx扩展
可以在这里(http://pecl.php.net/package/sphinx)找到sphinx的php扩展源码,注意,使用phpize,configure的时候可能会要求要安装libsphinxclient,它在coreseek-4.1-beta/csft-4.1/api/libsphinxclient/里面能找到,编译安装它以后就可以configure,make,生成动态so文件了。
3、 给服务提供配置文件 (源码目录下有样例: /coreseek-4.1-beta/testpack/etc/csft_mysql.conf)
#源定义
source study
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = select id,title,content,group_id from documents;
// 这里使用select 将想要被用于检索的索引字段查出来,缓存于Sphinx服务器中,sql_query第一列id需为整数,title、content作为字符串/文本字段,被全文索引
sql_query_info = SELECT * FROM documents where id=$id
#仅被命令行搜索所用,用来获取和显示文档信息,目前仅对MySQL有效,且仅用于调试目的。此查询为每个文档ID获取CLI搜索工具要显示的文档信息。它需要包含$id
宏,以此来对应到查询的文档的ID。
}
#index定义
index study
{
source = study #对应的source名称
path = /usr/local/coreseek/var/data/study
docinfo = extern
mlock = 0
morphology = none //不使用任何词形处理器
min_word_len = 1 //最小索引词长度。可选选项,默认为1(索引任何词)
html_strip = 0
charset_dictpath = /usr/local/mmseg3/etc/ //设置中文分词词典所在的目录
#charset_dictpath = etc/
charset_type = zh_cn.utf-8
}
source mysql
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = tuchao
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = SELECT id, title, abstract FROM ic_video
sql_query_info = SELECT * FROM ic_video where id=$id
}
index mysql
{
source = mysql
path = /usr/local/coreseek/var/data/mysql
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
charset_dictpath = /usr/local/mmseg3/etc/
#charset_dictpath = etc/
charset_type = zh_cn.utf-8
}
source qupeiyin
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = tuchao2
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = SELECT id, title, description FROM course
sql_query_info = SELECT * FROM course where id=$id
}
index qupeiyin
{
source = qupeiyin
path = /usr/local/coreseek/var/data/qupeiyin
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
charset_dictpath = /usr/local/mmseg3/etc/
#charset_dictpath = etc/
charset_type = zh_cn.utf-8
}
#全局index定义
indexer
{
mem_limit = 128M //索引过程内存限制,indexer不会超越的强制内存限制,设置太低会影响索引速度,一般为256M~1024M,最大限制是2048M.
}
#searchd服务定义
searchd
{
listen = 9312
read_timeout = 5 //网络客户端请求的读超时时间, searchd
强制关闭在此时间内未能成功发出查询的客户端连接。
max_children = 30 //子进程的最大数量,任何时候不可能有比此设置值更多的搜索同时运行。当达到限制时,新的输入客户端会被用临时失败(SEARCH_RETRY)状态码驳回;
max_matches = 1000 //为每个索引所保持并返回给客户端的匹配数目的最大值
seamless_rotate = 1 //启用无缝轮换,数据轮换时不暂停搜索服务。
preopen_indexes = 0
unlink_old = 1 //索引轮换成功之后,是否删除以.old为扩展名的索引拷贝。可选选项,默认为1(删除这些索引拷贝)。
pid_file = /usr/local/coreseek/var/log/searchd_mysql.pid
log = /usr/local/coreseek/var/log/searchd_mysql.log
query_log = /usr/local/coreseek/var/log/query_mysql.log
}
在写配置文件的时候,sourece名称可以与index名称不一样,但是path后的名称一定要和index定义的名称一致。
4、提供服务启动脚本
#!/bin/bash
#
# searchd - this script start and stop the searchd daemon
#
# chkconfig - 85 20
# description:
#
# processname: searchd
# config: /usr/local/coreseek/etc/csft_mysql.conf
. /etc/rc.d/init.d/functions
searchd="/usr/local/coreseek/bin/searchd"
prog=$(basename $searchd)
conf_file="/usr/local/coreseek/etc/csft_mysql.conf"
lockfile="/var/lock/subsys/searchd"
start() {
[ -e $lockfile ] && echo "searchd is already start" && exit 0
[ -x $searchd ] || exit 1
[ -f $conf_file ] || exit 2
echo -n "Starting $prog:"
daemon $searchd -c $conf_file
retval=$?
echo
if [ $retval -eq 0 ]; then
touch $lockfile
else
echo "$prog is starting failed"
fi
return $retval
}
stop() {
echo -n $"Stopping $prog:"
killproc $prog -QUIT
retval=$?
echo
if [ $retval -eq 0 ]; then
rm -rf $lockfile
fi
return $retval
}
restart() {
stop
sleep 1
start
}
indexer() {
/usr/local/coreseek/bin/indexer -c $conf_file --all
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
indexer)
indexer
;;
*)
echo "Usage:$0 {start|stop|restart|indexer}"
exit 2
esac
5、 重建全部索引
# /etc/init.d/searchd indexer
6、 启动searchd服务
# service searchd start
7、 提供PHP测试程序
<?php
$s = new SphinxClient;
$s->setServer("localhost", 9312);
$s->setArrayResult(true);
$s->setSelect();
$s->setMatchMode(SPH_MATCH_ALL);
//SPH_MATCH_ALL这个检索方法表示只显示匹配到的数据ID,并进行分词。SPH_MATCH_ANY表示先将搜索的内容进行分词,输出每个分词匹配到的数据ID。
$result1 = $s->query('乔布斯','mysql');
$result2 = $s->query('搞笑','qupeiyin');
$result3 = $s->query('Google','study');
print_r($result1);
print_r($result2);
print_r($result3);
?>
8、测试服务
我可以在httpd服务器指定的目录下创建一个test.php拷贝以上代码,根据自己的数据库数据做更改后保存。
这一句我要讲下: $result1 = $s->query('乔布斯','mysql'); “乔布斯“是搜索的关键词,后面的’mysql ’对应的是定义在csft_mysql.conf中的索引名称。表示从哪个索引中找
以下是用浏览器访问test.php返回的结果:
首先返回结果是在mysql索引中搜索关键词‘乔布斯’ 的,可以看到在id=>38 、id=>39 有匹配到,而且对搜集内容进行了分词。
[matches] => Array ( [0] => Array ([id] => 38 [weight] => 6 [attrs] => Array ( ) ) [1] => Array ( [id]=> 39 [weight] => 3 [attrs] => Array ( ) ) ) [total] => 2 [total_found]=> 2 [time] => 0.002 [words] => Array ( [乔] =>Array ( [docs] => 2 [hits] => 3 ) [布] => Array ([docs] => 2 [hits] => 3 ) [斯] => Array ( [docs] => 2 [hits] => 3 ) ) )
我们上MySQL服务器查找对应ID来验证:
我们再分析后续的输出结果,在qupeiyin索引中搜索‘ 搞笑’ 关键词,这里可以看到在id=>29 、 id=>518 有匹配到.
Array ( [error] => [warning] =>[status] => 0 [fields] => Array ( [0] => title [1] => description )[attrs] => Array ( ) [matches] => Array ( [0] => Array ( [id] => 29 [weight] => 1 [attrs] => Array () ) [1] => Array ( [id] => 518 [weight]=> 1 [attrs] => Array ( ) ) ) [total] => 2 [total_found] => 2[time] => 0.002 [words] => Array ( [搞笑] => Array ([docs] => 2 [hits] => 2 ) ) )
我们再来到数据库验证:
第三个输出也是可以找到对应的数据的,笔者就不上图了,由此可以看出,在对应的ID号确实能找到匹配的数据。