当你在面对庞大的数据对全文索引有需求时,可能会去尝试使用mysql自带的全文索引,但又苦于效率太差对项目做不到质的提升时。

那么我给大家隆重的介绍一个技术:Sphinx/Coreseek

001 什么是Sphinx

Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。意图为其他应用提供高速、低空间占用、高结果 相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从标准输入读取特定格式 的XML数据。通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS 的原生支持)

010 Sphinx的特性

* 高速的建立索引(在当代CPU上,峰值性能可达到10 MB/秒);
* 高性能的搜索(在2 – 4GB 的文本数据上,平均每次检索响应时间小于0.1秒);
* 可处理海量数据(目前已知可以处理超过100 GB的文本数据, 在单一CPU的系统上可 处理100 M 文档);
* 提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;
* 支持分布式搜索;
* 支持短语搜索
* 提供文档摘要生成
* 可作为MySQL的存储引擎提供搜索服务;
* 支持布尔、短语、词语相似度等多种检索模式;
* 文档支持多个全文检索字段(最大不超过32个);
* 文档支持多个额外的属性信息(例如:分组信息,时间戳等);
* 支持断词;

011 什么是Coreseek

Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和信息处理领域,适用于行业/垂直搜索、论坛/站内搜索、数据库搜索、文档/文献检索、信息检索、数据挖掘等应用场景,用户可以免费下载使用。 简单的来说,coreseek就是sphinx的中文支持版本。

100 sphinx/coreseek 工作脑图


101 安装使用 (既然我们天天和中文打交道,那么我们就直接安装coreseek)

1.安装依赖
yum install make gcc gcc++gcc-c++libtool autoconf automake imake mysql-devellibxml2-develexpat-devel 2.下载coreseek(地址可能失效,网上随意寻找)并解压

wget http://files.opstool.com/man/coreseek-4.1-beta.tar.gz

ar -xzvf coreseek-4.1-beta.tar.gz

cd coreseek-4.1-beta

3.安装mmseg(中文分词插件,集成与coreseek中)

cd mmseg-3.2.14

./bootstrap

./configure --prefix=/usr/local/coreseek-4.1

make && make install

make clean

(报错1:could not read symbols: File in wrong format collect2: ld 返回 1 make: *** [all] 错误 1)

解决方案:先make clean 然后再make 或者手动删除32位的链接对象后再重新编译

4.安装csft

先编辑configure.ac,修改 AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 为 AM_INIT_AUTOMAKE([-Wall foreign])

cd csft-4.1/

./buildconf.sh

./configure --prefix=/usr/local/coreseek-4.1 --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/coreseek-4.1/include/mmseg/ --with-mmseg-libs=/usr/local/coreseek-4.1/lib/ --with-mysql

make &&make install

make clean

安装过程中如果出现warning不用管,出现error处理error,这里我出现了一个ExprEval未定义的错误,那么修改 src/sphinxexpr.cpp 文件,将该文件中的 1013、1047、1080 行的 ExprEval 改为 this->ExprEval即可

注意:如果你的安装路径与配置文件里的默认安装路径不一致的话,开启服务前请务必先修改默认路径,并把相对路径改为绝对路径

5.测试

进入testpack文件夹

cat ./var/test/test.xml    #此时文本应该正确显示中文

/usr/local/mmseg/bin/mmseg  -d  /usr/local/mmseg/etc  var/test/test.xml #整篇文章进行分词

/usr/local/coreseek/bin/indexer -c etc/csft.conf --all   #创建索引

/usr/local/coreseek/bin/search -c etc/csft.conf 网络搜索 #搜索关键字 网络搜索


/usr/local/coreseek/bin/searchd -c etc/csft.conf                       #正常开启搜索服务

/usr/local/coreseek/bin/searchd -c etc/csft.conf--stop             #如要停止搜索服务

/usr/local/coreseek/bin/indexer -c etc/csft.conf--all --rotate     #如要已启动服务,要更新索引

110 如何与mysql关联,并生成索引给PHP使用

目前我们使用csft.conf配置文件已经测试成功,我发现在解压的安装包里只有testpack是后期需要的文件夹了,那么可以直接把此文件夹放到coreseek文件夹当中把安装包文件删掉

现在我们来配置csft_mysql.conf配置文件

#MySQL数据源配置,详情请查看:http://www.coreseek.cn/products-install/mysql/
#请先将var/test/documents.sql导入数据库,并配置好以下的MySQL用户密码数据库

#源定义
source mysql
{
type = mysql

sql_host = 127.0.0.1
sql_user = root
sql_pass = ****
sql_db = ****
sql_port = 3306
sql_query_pre = SET NAMES utf8

sql_query = SELECT id, tag_name, title, content_abridge,img, url,create_time FROM blog_article
#sql_query第一列id需为整数
#title、content作>为字符串/文本字段,被全文索引
sql_attr_uint = id #从SQL读取到的值必须为整数
sql_field_string = title
sql_field_string = content_abridge
sql_field_string = url
sql_field_string = img
sql_field_string = tag_name
sql_attr_timestamp = create_time #从SQL读取到的值必须为整数,作为时间>属性

sql_query_info_pre = SET NAMES utf8 #命令行查询时,设置正确的字符集
sql_query_info = SELECT * FROM blog_article WHERE id=$id #命令行>查询时,从数据库读取原始数据信息
}

#index定义
index mysql
{
source = mysql #对应的source名称
path = /usr/local/coreseek/var/data/mysql #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0

#中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/
charset_dictpath = /usr/local/coreseek_gl/mmseg/etc/ #BSD、Linux环境下设置,/符号结尾
#charset_dictpath = etc/ #Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/...
charset_type = zh_cn.utf-8
}

#全局index定义
indexer
{
mem_limit = 128M
}

#searchd服务定义
searchd
{
listen = 9312
read_timeout = 5
max_children = 30
max_matches = 1000
seamless_rotate = 0
preopen_indexes = 0
unlink_old = 1
pid_file = /usr/local/coreseek/var/log/searchd_mysql.pid #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
log = /usr/local/coreseek/var/log/searchd_mysql.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
query_log = /usr/local/coreseek/var/log/query_mysql.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
binlog_path = #关闭binlog日志
}

这样搜索的话就会从索引文件中查出id, tag_name, title, content_abridge,img, url,create_time 字段。

/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/testpack/etc/csft_mysql.conf     #创建索引

如果提示:FATAL: failed to lock /usr/local/coreseek/var/data/xxxx.spl: Resource temporarily unavailable, will not index. Try --rotate option.

则尝试重建索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/testpack/etc/csft_mysql.conf --all --rotate 重建索引

/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/testpack/etc/csft_mysql.conf --stop 停止服务

开启服务后我们找到testpack/api/sphinxapi.php 这个文件,将这个文件引入到我们的项目中,写一个脚本并引入这个文件 下列为PHP脚本:

require('sphinxapi.php');

private function search(){
    $cl = new \SphinxClient();

    $q = "架构";
    $host = "127.0.0.1";
    $port = 9312;
     $index = "mysql";

    $cl->SetServer ( $host, $port );
    $cl->SetConnectTimeout ( 1 );
    $cl->SetArrayResult ( true );
    //匹配查询词中的任意一个
    $cl->SetMatchMode(SPH_MATCH_ANY);
    $res = $cl->Query ( $q, $index );
    echo "<pre>";var_dump($res);exit();

}

查看打印即可发现,搜索到的索引已经展现给了前端

为PHP使用时还可以使用php自带的扩展包开发,详情自行搜索

有关PHP使用全文索引的更多信息推荐这篇文章 Sphinx大全

111 下列为网络上搜索出来在安装或运行coreseek时出现的问题以及解决方法

1、测试mmseg分词的时候

执行   /usr/local/coreseek/bin/indexer -c etc/csft.conf –all

提示下面的错误:
/usr/local/coreseek/bin/indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory

原因:sphinx indexer的依赖库ibmysqlclient.so.18找不到。

解决办法:
vi /etc/ld.so.conf
加入 /usr/local/mysql/lib
然后运行 ldconfig   问题解决

2、执行索引的时候
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf –all –rotate

提示下面的错误:
FATAL: failed to open /usr/local/coreseek/var/data/article/.tmp.spl: No such file or directory, will not index. Try –rotate option.

原因:source源找不到mysql.sock

解决办法:在配置文件csft.conf(自己创建的文件)的 source源 加入下面的代码

sql_sock   = /tmp/mysql.sock

3、执行索引的时候,出现的警告,导致索引没创建成功
WARNING: failed to open pid_file '/usr/local/coreseek/var/log/searchd_ttd_search.pid'.
WARNING: indices NOT rotated.

原因:找不到searchd_ttd_search.pid文件

解决办法:在’/usr/local/coreseek/var/log 下创建searchd_ttd_search.pid文件

再执行/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf –all –rotate
出现了另外一个警告:

WARNING: failed to scanf pid from pid_file '/usr/local/coreseek/var/log/searchd_ttd_search.pid'.
WARNING: indices NOT rotated.

原因:虽然创建了searchd_ttd_search.pid文件,但是里面没有写入进程id

解决办法(根本原因):在执行索引之前没有启动searchd服务,因此执行下面的命令

/usr/local/coreseek/bin/searchd –config /usr/local/coreseek/etc/csft.conf

4、执行索引时
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf –all –rotate

提示下面的错误:
FATAL: failed to open /usr/local/coreseek/var/data/article.tmp.spl: Permission denied, will not index. Try –rotate option.
原因:权限问题
解决办法:使用root用户来执行命令