1. 云栖社区>
  2. PHP教程>
  3. 正文

sphinx与coreseek

作者:用户 来源:互联网 时间:2017-12-01 17:29:01

sphinx与coreseek - 摘要: 本文讲的是sphinx与coreseek, Sphinx 1 下载sphinx http://sphinxsearch.com/2 编译安装tar -zxvf sphinx.tar.gz./configure --prefix=/usr/local/sphinx --with-m

Sphinx


1 下载sphinx 
http://sphinxsearch.com/

2 编译安装
tar -zxvf sphinx.tar.gz
./configure --prefix=/usr/local/sphinx --with-mysql=/usr/local/mysql make && make install
Sphinx中重要的三个命令,(Sphinx安装的bin目录下)
Indexer 创建索引命令。Searchd 启动进程命令。Search 命令行搜索命令。

3 准备
导入example.sql
mysql -u test < /usr/local/sphinx/etc/example.sql

4 配置sphinx.conf
cp sphinx.conf.dist sphinx.conf

sphinx.conf包含几个代码段
主数据源:
source main{
}
增量数据源:
source delta:main{
}

主数据索引:
index main{
}
增量数据索引:
index delta:main{
}

分布式索引:
index dist1{
}
实时索引:
index rt{
}

索引器:
indexer{
}
服务进程:
searchd{
}

公用设置
common{
}


创建索引
Sphinx的配置文件配置完成,数据也做了,开始创建索引:
创建索引命令:indexer
-c 指定配置文件
--all 对所有索引重新编制索引
--rotate 用于轮换索引,主要是再不停止服务的时候,增加索引
--merge 合并索引
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all
如果报错:/usr/local/sphinx/bin/indexer: error while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or directory

locate libmysqlclient 找到libmysqlclient.so.16文件路径
cp /usr/local/mysql/lib/mysql/libmysqlclient.so.16 /usr/lib/libmysqlclient.so.16

测试
检查数据命令:search
/usr/local/sphinx/bin/search -c /usr/local/sphinx/etc/sphinx.conf test



Coreseek


安装:
http://www.coreseek.cn下载
解压并cd到mmseg目录:
./configure --prefix=/usr/local/mmseg
如果报cannot find input file: src/Makefile.in错运行automake
关于automake:http://blog.csdn.net/fb408487792/article/details/45391171
运行/usr/local/mmseg/bin/mmseg 有信息表示成功

cd到csft目录:
./configure --prefix=/usr/local/coreseek --with-mysql=/usr/local/mysql --with-mmseg=/usr/local/mmseg --with-mmseg-includes=/usr/local/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg/lib/
make && make install

配置带有中文分词的sphinx配置文件
配置文件和上面的步骤一样,只不过是在coreseek中,有几个地方需要注意。
注意:coreseek中得配置文件是csft.conf,而不是sphinx.conf
cd /usr/local/coreseek/etc
cp sphinx.conf.dist csft.conf
vim csft.conf
其他地方都一样,对照下面不一样的地方修改
index test1
{
#stopwords = /data/stopwords.txt
#wordforms = /data/wordforms.txt
#exceptions = /data/exceptions.txt
#charset_type = sbcs
添加下面这两行,意思是把中文分词加入到配置文件中
charset_type = zh_cn.utf-8
charset_dictpath = /usr/local/mmseg/etc/ #你安装mmseg的目录
}

创建索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf --all
再次测试搜索中文
/usr/local/coreseek/bin/search [-a] -c /usr/local/coreseek/etc/csft.conf '配置'
注意:如果你设置的coreseek配置文件为csft.conf,则inder、search和searchd时不用带上-c /usr/local/coreseek/etc/csft.conf,因为默认就是去寻找这个文件.


PHP去使用Sphinx


Sphinx集成到PHP程序中,有两种方式:
1.Sphinx php模块
2.Sphinxapi类


使用 Sphinx步骤:
1、首先得有数据
2、建立Sphinx配置文件
3、生成索引
4、启动Searchd服务进程,并开户端口9312
5、用PHP客户程序去连接Sphinx服务

一、启用sphinx服务
想要在程序中使用Sphinx必须开启Sphinx服务
启动进程命令: searchd
-c #指定配置文件
--stop #是停止服务
--pidfile #用来显式指定一个 PID 文件
-p #指定端口
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf
注意:这里启动的服务是searchd,不是search
Sphinx默认的端口是9312端口

二、用PHP连接使用Sphinx程序
(1)全PHP加载Sphinx模块

wget http://pecl.php.net/get/sphinx-1.1.0.tgz 
tar zxf sphinx-1.1.0.tgz 
cd /www/soft/sphinx-1.1.0 
/usr/local/php/bin/phpize 
./configure --with-php-config=/usr/local/webserver/php/bin/php-config
如果提示: checking for libsphinxclient headers in default path... not found configure: 
error: Cannot find libsphinxclient headers 
libsphinxclient在csft/api/libsphinxclient
cd libsphinxclient/ 
./configure 
make && make install 
安装完libsphinxclient,继续安装sphinx扩展
cd /www/soft/sphinx-1.1.0 
/usr/local/php/bin/phpize 
./configure --with-php-config=/usr/local/php/bin/php-config 
make && make install 
cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/
看到sphinx.so 
vi /usr/local/webserver/php/etc/php.ini 
加入extension = sphinx.so
/usr/local/apache2/bin/apachectl restart
测试Sphinx模块,http://127.0.0.1/phpinfo.php

(2)、使用API类连接Sphinx程序
需要到coreseek解压包中找到sphinxapi.php文件,拷贝到程序目录下

include 'sphinxapi.php';$sphinx = new SphinxClient();$sphinx->SetServer("localhost", 9312);#建立连接,第一个参数sphinx服务器地址,第二个sphinx监听端口$result = $sphinx->query($keyword,"*");#执行查询,第一个参数查询的关键字,第二个查询的索引名称,多个索引名称用,分开,也可以用*表示全部索引,其中包括增量索引print_r($result);

得到类似下面的数组结构
[matches] => Array ( //匹配的结果
[1] => Array
[weight] => 4
[attrs] => Array
[group_id] => 1
[date_added] => 1319127367
#一个多维的数组,下标[6]是你匹配包含关键字的文档id,id对应的数组,[weight]是权重,[attrs]是属性,我们在配置文件中指定的
[total] => 2  #此查询在服务器检索所得的匹配文档总数
[total_found] => 2  #索引中匹配文档的总数
[time] => 0.009  #这个是我们这次查询所用的时间
[words] => Array (
[测试] => Array
[docs] => 2 在文档中出现多少次(content 字段中)
[hits] => 6 一共出现多少次
while($row=$result->fetch_row()){#循环体开始解析看下结果.高亮我们需要用到 buildExcerpts 这个函数,php 手册中语法格式:public array SphinxClient::buildExcerpts ( array $docs , string $index , string $words [, array $opts ])#返回的是一个数组,一共有四个参数#第一个参数是从数据库中查询的结果集#第二个参数是索引的名字#第三个参数是要高亮显示的关键字#第四个参数是显示的字格式化$opts = array(#格式化摘要,高亮字体设置#在匹配关键字之前插入的字符串,默认是<b>"before_match" => "<span style='font-weight:bold;color:red'>",#在匹配关键字之后插入的字符串,默认是</b>"after_match" => "</span>",#在摘要段落之前插入的字符串默认 „"chunk_separator" => " ... ",);$res=$sphinx->buildExcerpts($row,"index",$keyword,$opts);echo "<font size=4>".$res[0]."</font></a></br>"; 标题echo "<font size=2>".$res[1]."</font></br>"; 摘要echo $res[2]."</p>"; 添加时间}

三、匹配模式

匹配模式:SetMatchMode(设置匹配模式)
原型:function SetMatchMode ( $mode )
SPH_MATCH_ALL 匹配所有查询词(默认模式).
SPH_MATCH_ANY 匹配查询词中的任意一个.
SPH_MATCH_PHRASE 将整个查询看作一个词组,要求按顺序完整匹配.
SPH_MATCH_BOOLEAN 将查询看作一个布尔表达式.
SPH_MATCH_EXTENDED 将查询看作一个 Sphinx 内部查询语言的表达式.
SPH_MATCH_FULLSCAN 使用完全扫描,忽略查询词汇.
SPH_MATCH_EXTENDED2 类似 SPH_MATCH_EXTENDED ,并支持评分和权重

四、Sphinx实时索引(旧版)
"主索引+增量索引"思路
1、创建一个计数器
一个简单的实现是,在数据库中增加一个计数表,记录将文档集分为两个部分的文档 ID,每次重新构建主索引时,更新这个表
先在 mysql 中插入一个计数表
CREATE TABLE sph_counter( counter_id INTEGER PRIMARY KEY NOT NULL, max_doc_id INTEGER NOT NULL);

2、再次修改配置文件
主数据源,继承数据源,主索引,继承索引。(继承索引也就是增量索引)。
主数据源里面:我们需要把欲查询语句改成下面的语句:
Vi /usr/local/coreseek/etc/csft.conf
Source main{#加一句sql_query_presql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM post#并修改sql_query= /SELECT id,title, content FROM post /WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)}继承数据源:source delta : main{sql_query_pre = SET NAMES utf8sql_query= /SELECT id,title, content FROM post /WHERE id>(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)}主索引:#名字最好与数据源相应Index main {source = mainpath = /usr/local/coreseek/var/data/main}继承索引(也是增量索引)index delta:main{source= deltapath= /usr/local/coreseek/var/data/delta}

注意:如果你增量索引的 source 配置中只有 id,content 三项
而主索引的 source 配置中有 id, title,content 四项,合并的时候会报属性数量不匹配,如:
Delta:sql_query = SELECT id, title,content FROM post
Main:sql_query=SELECT id,title,date,content FROM post

3、测试增量索引+主索引
如果想测试增量索引是否成功,往数据库表中插入数据,查找是否能够检索到,这个时候检索应该为空,然后,单独重建增量索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf delta
查看是否将新的记录进行了索引,如果成功
此时,再用/usr/local/coreseek/bin/search 工具来检索,能够看到,在主索引中检索到的结果为0,而在增量中检索到结果。当然,前提条件是,检索的词,只在后来插入的数据中存在

4、实时更新索引

我们需要建立两个脚本,还要用到计划任务
建立一个主索引和增量索引的脚本
main.sh delta.sh

在增量索引中写下delta.sh
#!/bin/bash
#delta.sh
/usr/local/coreseek/bin/indexer delta >>/usr/local/coreseek/var/log/delta.log

主索引中写下:main.sh意思就是合并索引
#!/bin/bash
#main.sh
/usr/local/coreseek/bin/indexer main >>/usr/local/coreseek/var/log/merge.log
最后,我们需要脚本能够自动运行,以实现增量索引每5分钟重新建立,和主索引只在凌晨2:30时重新建立.
脚本写好了,我们需要建立计划任务
crontab -e
*/10 * * * * /usr/local/coreseek/etc/delta.sh
30 2 * * * /usr/local/coreseek/etc/main.sh
脚本权限:
chmod a+x delta.sh
chmod a+x main.sh
可以查看日志文件

实时索引(新)
据官方透露,目前已经开始可以在生产环境使用
他可以使用sphinxQL用mysql协议进行查询添加更新数据
看起来像一个mysql一样,不过他支持全文检索,新更新进去的数据会自动索引达到实时索引的程度
但是他也有缺点,比如经常更新会导致内存增长
在内存中的数据如果不及时写入硬盘,出现中断会丢失数据
只支持部分sql语句,前段时间简单测试了一下
如果数据量巨大他会变得缓慢,在内存数据往硬盘写的时候会卡几秒
index rt{    type = rt    rt_mem_limit = 512M    path = @[email protected]/data/rt    rt_field = title    rt_field = content    rt_attr_uint = gid}searchd{    listen       = 9306:mysql41 #searchd支持mysql协议连接的端口    max_matches  = 3000 #在mysql协议内查询出来的数据只会返回3000条,即使使用limit语句也是如此}
sphinx的实时索引配置本身并不需要数据源(source),它的数据是要通过程序利用mysql41协议的方式。
mysql -P 9306 -h 127.0.0.1 连接sphinx进行测试


五、分布式索引
分布式是为了改善查询延迟问题和提高多服务器、多 CPU 或多核环境下的吞吐率,对于大量数据(即十亿级的记录数和 TB 级的文本量)上的搜索应用来说是很关键的
分布式思想:对数据进行水平分区(HP,Horizontally partition),然后并行处理,
当searchd收到一个对分布式索引的查询时,它做如下操作
1. 连接到远程代理.
2. 执行查询.
3. 对本地索引进行查询.
4. 接收来自远程代理的搜索结果.
5. 将所有结果合并,删除重复项.
6. 将合并后的结果返回给客户端.
index dist
{
type = distributed
local = chunk1
agent = localhost:9312:chunk2 本地
agent = 192.168.100.2:9312:chunk3 远程
agent = 192.168.100.3:9312:chunk4 远程
}


六.PHP代码实例
$keyword=$_POST['word'];$sphinx=new SphinxClient();$sphinx->SetServer("localhost",9312);$sphinx->SetMatchMode(SPH_MATCH_ANY);//$sphinx->setLimits(0,0);$result=$sphinx->query("$keyword","*");//echo "<pre>";//print_r($result);//echo "</pre>";$ids=join(",",array_keys($result['matches']));mysql_connect("localhost","root","root");mysql_select_db("test");$sql="select * from post where id in({$ids})";mysql_query("set names utf8");$rst=mysql_query($sql);$opts=array("before_match"=>"<button style='font-weight:bold;color:#f00'>","after_match"=>"</button>");while($row=mysql_fetch_assoc($rst)){$rst2=$sphinx->buildExcerpts($row,"main",$keyword,$opts);echo "{$rst2[0]}<br>";echo "{$rst2[1]}<br>";echo "{$rst2[2]}<br>";}

更多关于sphinx,请见手册:http://sphinxsearch.com/docs/current.html
更多关于coreseek,请参见手册:http://www.coreseek.cn/docs/coreseek_4.1-sphinx_2.0.1-beta.html

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索,以便于您获取更多的相关知识。

弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率

40+云计算产品,6个月免费体验

稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一

云服务器9.9元/月,大学必备