首先运行php-fpm(设置开机启动的略过)
/usr/local/php/sbin/php-fpm -c /usr/local/php/php.ini
启动coreseek服务
首先检测是否开启 netstat -tunlp | grep searchd
#启动coreseek
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf
#停止coreseek
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf --stop
php代码如下
<?php
$s = new SphinxClient();
$s->setServer("192.168.2.156", 9312);
$s->setMatchMode(SPH_MATCH_ANY);
$s->setMaxQueryTime(3);
$result = $s->query("测试",'test');
print_r($result);
?>
页面显示
Array ( [error] => [warning] => [status] => 0 [fields] => Array ( [0] => title [1] => content ) [attrs] => Array ( ) [matches] => Array ( [1] => Array ( [weight] => 2 [attrs] => Array ( ) ) [5] => Array ( [weight] => 2 [attrs] => Array ( ) ) [4] => Array ( [weight] => 1 [attrs] => Array ( ) ) ) [total] => 3 [total_found] => 3 [time] => 0.003 [words] => Array ( [测试] => Array ( [docs] => 1 [hits] => 2 ) ) )
则为正常
接下来,我忘关联的数据库的表中添加两条信息,重新执行程序,结果没有变化,需要重新生成索引
cd /usr/local/coreseek/bin/
执行 ./indexer --all 更新索引
测试搜索 ./searchd "测试"
发现新添加的记录也搜索出来了,执行php程序如下:
Array ( [error] => [warning] => [status] => 0 [fields] => Array ( [0] => title [1] => content ) [attrs] => Array ( ) [matches] => Array ( [1] => Array ( [weight] => 2 [attrs] => Array ( ) ) [5] => Array ( [weight] => 2 [attrs] => Array ( ) ) [4] => Array ( [weight] => 1 [attrs] => Array ( ) ) ) [total] => 3 [total_found] => 3 [time] => 0.003 [words] => Array ( [测试] => Array ( [docs] => 3 [hits] => 5 ) ) )
从上面可以看出Query并不能全部取得我们想要的记录内容,比如说Title,Contents字段就没有取出来,根据官方的说明是sphinx并没 有连到mysql去取记录,只是根据它自己的索引内容进行计算,因此如果想用sphinxAPI去取得我们想要的记录,还必须将Query的结果为依据去 查询MySQL才可以得到最终我们想要的结果集。
首先我们要提取出主键
$ids = array_keys($result['matches']);
$ids = implode(',', $ids);
接下来我们希望我们从数据库中获得的结果中 搜索关键词字体高亮显示,那么我们需要用到sphinx扩展的一个函数 SphinxClient::buildExcerpts
官方的解释:
BuildExcerpts (产生文本摘要和高亮)
原型: function BuildExcerpts ( $docs, $index, $words, $opts=array() )
该函数用来产生文档片段(摘要)。连接到searchd,要求它从指定文档中产生片段(摘要),并返回结果。
$docs为包含各文档内容的数组。$index为包含索引名字的字符串。给定索引的不同设置(例如字符集、形态学、词形等方面的设置)会被使用。$words为包含需要高亮的关键字的字符串。它们会按索引的设置被处理。例如,如果英语取词干(stemming)在索引中被设置为允许,那么即使关键词是“shoe”,“shoes”这个词也会被高亮。从版本0.9.9-rc1开始,关键字可以包含通配符,与查询支持的star-syntax类似。$opts为包含其他可选的高亮参数的hash表:
"before_match":
在匹配的关键字前面插入的字符串。默认为"<b>"。
"after_match":
在匹配的关键字后面插入的字符串。默认为 "<b>".
"chunk_separator":
在摘要块(段落)之间插入的字符串。默认为" ... ".
"limit":
摘要最多包含的符号(码点)数。整数,默认为256.
"around":
每个关键词块左右选取的词的数目。整数,默认为5.
"exact_phrase":
是否仅高亮精确匹配的整个查询词组,而不是单独的关键词。布尔值,默认为false.
"single_passage":
是否仅抽取最佳的一个段落。布尔值,默认为false.
"weight_order":
对于抽取出的段落,要么根据相关度排序(权重下降),要么根据出现在文档中的顺序(位置递增)。布尔型,默认是false.
失败时返回false。成功时返回包含有片段(摘要)字符串的数组。
接下来实现这个功能,具体代码如下:
<?php
$s = new SphinxClient();
$s->setServer("192.168.2.156", 9312);
$s->setMatchMode(SPH_MATCH_ANY);
$s->setMaxQueryTime(3);
$result = $s->query("测试",'test');
$ids = array_keys($result['matches']);
$ids = implode(',', $ids);
//高亮关键词字体设置颜色
$opt = array(
'before_match' => '<strong style="color:#faa001">',
'after_match' => '</strong>',
);
//连接mysql
$con = mysql_connect("localhost","root","123456");
mysql_select_db("test",$con);
$sql = "select * from test where id in ({$ids})";
$query = mysql_query($sql);
$count = mysql_num_rows($query);
while($list = mysql_fetch_array($query)) {
//这里将标题和内容部门的关键词设置为高亮字体颜色
$highlightTextList = $s->buildExcerpts(
array(
$list['title'],
$list['content'],
),
'test',
'测试',
$opt
);
//print_r($highlightTextList);
//那么标题和内容就不是 $list['title'] 和 $list['content']的了,而是我们处理结果的$highlightTextList数组
echo "id: {$list['id']}<br />title: {$highlightTextList[0]}<br />content: {$highlightTextList[1]}<br />";
echo "<hr />";
}
?>
分页
使用函数SetLimits (设置结果集偏移量)
原型: function SetLimits ( $offset, $limit, $max_matches=0, $cutoff=0 )
这里挺简单直接贴代码,注意和php分页一样需要放在query查询前面执行
//设置分页
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$pagesize = 2;
$offset = ($page - 1) * $pagesize;
$s->setLimits($offset, $pagesize);
最终代码如下:
<?php
$s = new SphinxClient();
$s->setServer("192.168.0.156", 9312);
$s->setMatchMode(SPH_MATCH_ANY);
$s->setMaxQueryTime(3);
//设置分页
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$pagesize = 2;
$offset = ($page - 1) * $pagesize;
$s->setLimits($offset, $pagesize);
$result = $s->query("测试",'test');
$ids = array_keys($result['matches']);
$ids = implode(',', $ids);
$opt = array(
'before_match' => '<strong style="color:#faa001">',
'after_match' => '</strong>',
);
//连接mysql
$con = mysql_connect("localhost","root","123456");
mysql_select_db("test",$con);
$sql = "select * from test where id in ({$ids})";
$query = mysql_query($sql);
$count = mysql_num_rows($query);
while($list = mysql_fetch_array($query)) {
$highlightTextList = $s->buildExcerpts(
array(
$list['title'],
$list['content'],
),
'test',
'测试',
$opt
);
//print_r($highlightTextList);
echo "id: {$list['id']}<br />title: {$highlightTextList[0]}<br />content: {$highlightTextList[1]}<br />";
echo "<hr />";
}
?>
当然我们不管是使用框架或者cms,都会有开源的php-sphinx类和mysql操作类,这样代码就不用这么搓,这里只是记录下实现原理