Sphinx实验手册
一、 环境准备:
源代码编译的LAMP环境
CentOS 6.3 Linux版本
Mysql-5.5.23 mysql版本
Apache-2.4.7 apache版本
Php-5.4.25 php版本
coreseek-3.2.14 coreseek版本
准备mysql数据
我们需要一些数据,这里我们用安装mysql自带的test库进行测试
准备一个post贴子表,其中该表的字段如下:
/usr/local/mysql/bin/mysql -uroot -p
USE test;
CREATE TABLE post(
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) ,
content TEXT
)ENGINE=MyISAM DEFAULT CHARSET=UTF8;
测试数据例如:
INSERT INTO post (title,content) VALUES (‘lamp兄弟连‘,‘人类已经无法阻止兄弟连了‘);
INSERT INTO post (title,content) VALUES (‘PHP简介‘,‘有人说,PHP是拍黄片,你信了吗‘);
真正实验数据后续分发。
Coreseek-带有中文分词的Sphinx
Coreseek介绍:
Sphinx默认不支持中文索引及检索,基于Sphinx开发了Coreseek 全文检索服务器,Coreseek应该是现在用的最多的Sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg包含mmseg中文分词
二、 安装Coreseek
(1)、下载中文分词包
http://www.coreseek.cn 到官网去下载Coreseek,3.2.14为稳定版,最新4.1为测试版,即将发布5。
用winscp等工具上传到Linux的/lamp目录中
(2)、解压安装
cd /lamp
tar -zxvf coreseek-3.2.14.tar.gz
进入到mmseg所在文件夹,先安装中文分词mmseg
cd /lamp/coreseek-3.2.14/mmseg-3.2.14/
./bootstrap #如果输出waring信息可以忽略。
./configure --prefix=/usr/local/mmseg
然后再进行编译和安装:
make && make install
然后运行mmseg,就能输入安装成功的信息了:
/usr/local/mmseg/bin/mmseg
出现下列信息,就证明mmseg中文分词已经安装好了。
接下来,我们要把Sphinx和mmseg结合起来
(1)、检测安装
进入coreseek目录,进行安装
cd /lamp/coreseek-3.2.14/csft-3.2.14/
./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/
//如果没有 ./configure 这个文件请进到coreseek目录下的testpack下api下的libsphinxclient下执行
./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
(2)、配置带有中文分词的sphinx配置文件
配置文件和上面的步骤一样,只不过是在coreseek中,有几个地方需要注意。
注意:coreseek中得配置文件也是csft.conf,而不是sphinx.conf
cd /usr/local/coreseek/etc
cp sphinx.conf.dist csft.conf
vim csft.conf
三、 配置文件
#################################################################
配置文件中有四种配置
source 数据源相关
index 索引相关
indexer 索引器相关(索引器是用来生成索引的命令)
searchd 服务进程相关
配置文件的格式有下面这几段
source main{ #配置了一个数据源作为主数据源,名称是main
}
source delta:main { #增量数据源,继承主数据源,名称是delta
} #继承后,相同的配置,不用再写一次了,只需要把不同的写出来
index ind_main{ #配置了一个主数据索引,索引的名称是ind_main
}
index delta:index_main{ #增量数据索引,继承主数据索引
}
index dist1{ #分布式索引(在别的服务器上的索引中检索)
}
indexer{ #索引器
}
searchd{ #服务进程
}
#################################################################
具体如下
主数据源,默认名是src1,方便管理,改为main
source main
{
type = mysql #数据库类型
sql_host = localhost # MySQL主机IP
sql_user = root # MySQL用户名
sql_pass = 123 # MySQL密码
sql_db = test # MySQL数据库
sql_port = 3306 # MySQL端口
sql_sock = /tmp/mysql.sock #linux下需要开启,指定sock文件,将#号注释去掉
sql_query_pre = SET NAMES UTF8 # MySQL检索编码(去掉注释)
sql_query_pre = SET SESSION query_cache_type=OFF #关闭缓存(去掉注释)
sql_query = \ #获取数据的SQL语句,反斜线“\”表示接着下一行
SELECT id, title, content FROM post
#sql_attr_uint = group_id #注释掉(排序字段)
#sql_attr_timestamp = date_added #注释掉(添加时间戳)
sql_query_info= SELECT * FROM post WHERE id=$id #这行将表名改正确,id是数据库中的主键字段
}
主数据源main到这里配置结束了
接下来这个是增量数据源配置示例,先注释掉,后面将单独进行配置
增量数据源
#source src1throttled : src1
#{
# sql_ranged_throttle = 100
#}
下面是主数据索引的配置示例,test1是主数据索引的名字,这里为了方便管理,修改为ind_main
主数据索引
index ind_main
{
source = main
#要对哪个数据源进行索引,这里对应上面主数据源的名字,将默认的src1改为main
path = /usr/local/coreseek/var/data/ind_main
#索引保存在什么地方,data目录下,最好与索引名字同名
#注释掉下面的几行
#stopwords = G:\data\stopwords.txt #可选设置,表示停止词文件,该文件中的词汇(也可以为单字)不参与搜索;文件格式为普通UTF-8文本文件,每行一个
#wordforms = G:\data\wordforms.txt词形字典。可选选项,默认为空。即将词的各种形态如 “walks”,“walked”,“walking”变为标准形式“walk”
#exceptions = /data/exceptions.txt #特例文件, 对于中文用户,这一选项无效。例如查询“ms windows”不会匹 配包含“MS Windows”的文档
#charset_type = sbcs #字符集编码类型,我们将在下面设置此项为zh_cn.utf-8
#添加下面这两行,意思是把中文分词加入到配置文件中
charset_type = zh_cn.utf-8 #表示启用中文分词功能,否则中文分词功能无效。需要source数据源之中,读取的数据编码字符集为UTF-8 。MySQL通过SET NAMES UTF8设定输出字符集为UTF-8,即使原始数据为GBK也可以。
charset_dictpath = /usr/local/mmseg/etc/ #中文词典目录 就是安装mmseg的目录,该目录下必须有uni.lib词典文件存在
}
其它选项不用改,到这里主数据索引配置完成
下面是增量数据源索引,由于前面已将增量数据源注释掉了,所以增量数据索引也不需要,注释掉即可
增量数据源索引
#index test1stemmed : test1
#{
# path = /usr/local/coreseek/var/data/test1stemmed
# morphology = stem_en
#}
接下来是分布式索引,只有这一台服务器,不需要分布式索引,也注释掉
分布式索引
#distributed index example
#index dist1
#{
#….
#agent_query_timeout = 3000
#}
将上面这些注释掉后,其实只留下了主数据源和主数据索引
接下来是indexer settings 索引器设置和searchd settings进程设置,默认即可
索引器
indexer
{
#默认即可,不用改
}
进程设置
searchd
{
#默认即可,不用改
}
整个配置完成
=============================================
注意,要确定数据库中的表,一定是UTF8字符集
在MySQL中用:\s 可以查看服务器信息
四、 测试使用
现在还没有生成索引文件,这个data目录是空的
ls /usr/local/coreseek/var/data
生成主数据索引
cd /usr/local/coreseek/bin
./indexer ind_main
mysql5.1报错
error while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or directory
原因是没有找到MySQL的libmysqlclient.so.16,从MySQL安装目录中copy一份过去
cp /usr/local/mysql/lib/mysql/libmysqlclient.so.16 /usr/lib #放到/lib或/usr/lib都行
mysql5.5报错
./bin/indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory
原因是没有找到MySQL的libmysqlclient.so.18,从MySQL安装目录中软连接过去
ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib/
两个版本mysql 的so文件路径不一样,需要了解即可。
重新生成索引
./indexer ind_main
using config file ‘/usr/local/coreseek/etc/csft.conf‘...
indexing index ‘ind_main‘...
collected 2 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 2 docs, 100 bytes
total 0.052 sec, 1921 bytes/sec, 38.42 docs/sec
total 1 reads, 0.000 sec, 0.2 kb/call avg, 0.0 msec/call avg
total 5 writes, 0.002 sec, 0.1 kb/call avg, 0.4 msec/call avg
然后再次查看data目录,生成了很多文件
ls /usr/local/coreseek/var/data
ind_main.spa ind_main.sph ind_main.spk ind_main.spp ind_main.spd ind_main.spi ind_main.spm
cd /usr/local/coreseek/bin
./search lamp
./search PHP
均成功搜索到内容
using config file ‘/usr/local/coreseek/etc/csft.conf‘...使用的是哪一个配置文件
index ‘test1‘: query ‘PHP ‘: returned 1 matches of 1 total in 0.007 sec在test1索引中返回1个匹配项,0.007秒
displaying matches:
1. document=2, weight=2
id=2 在id为2,title为PHP???,content为??PHP???,中文在命令行下乱码属正常现象
title=PHP??
content=????PHP?????????
words:
1. ‘php‘: 1 documents, 2 hits Coreseek Fulltext 3.2 [ Sphinx 0.9.9-release (r2117)]
php这个词,只在一篇文档中出现,词频为2,出现了两次
./search lamp兄弟连
displaying matches:
1. document=1, weight=5
id=1
title=lamp???
content=????????????
words:
1. ‘lamp‘: 1 documents, 1 hits 会自动帮我们拆词
2. ‘兄弟‘: 1 documents, 2 hits 兄弟这个词在一篇文章中出现,命中2次
3. ‘连‘: 1 documents, 2 hits 中文词典中,没有中“兄弟连”的词,所以被折成了“兄弟”+“连”
只要命令行能搜索到,php就能搜索到
启动服务
netstat -tunpl | grep 9312 查看端口是否有占用
./searchd 启动服务
using config file ‘/usr/local/coreseek/etc/csft.conf‘...
listening on all interfaces, port=9312
当服务启动后,从新生成索引时,需要加参数,不然会报错
./index ind_main --rotate
到此我们linux下的Sphinx中文分词已经安装完成了,并测试成功
五、 准备编译PHP文件环境
搭建Samba,创建共享目录方便Windows下开发
mount /dev/cdrom /mnt/cdrom
yum -y install samba
service smb start
smbpasswd -a jack # 新增一个jack用户
vi /etc/samba/smb.conf
[www]
path = /usr/local/apache2/htdocs
valid users = jack (多个用空格分开。如果没配置此项,所有用户都可以访问)
writable = yes (写权限)
testparm #测试samba配置文件语法错误
service smb restart
为samba用户jack设置ACL权限
setfacl -R -m u:jack:rwx /usr/local/apache2/htdocs
setfacl -R -m d:u:jack:rwx /usr/local/apache2/htdocs
vi /usr/local/apache2/etc/httpd.conf
User jack #默认是User daemon
Group jack
/usr/local/apache2/bin/apachectl restart
windows命令行连接
net use * /del /y
net use \\192.168.88.88 "your password" /user:jack
如何用PHP去使用Sphinx技术
在这篇中我们使用 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端口
如果出现这个问题:
说明端口已经被占用了,解决的办法是:netstat --tunpl | grep 9312找出进程 ID,
kill -9进程id,再开启就可以了
二、用PHP连接使用Sphinx程序
使用API类连接Sphinx程序
需要到coreseek解压包中找到sphinxapi.php文件,放到程序目录下
cp /lamp/coreseek-3.2.14/csft-3.2.14/api/sphinxapi.php /usr/local/apache2/htdocs/
vi /usr/local/apache2/htdocs/sphinx_test.php
<?php
include ‘sphinxapi.php‘; //加载Sphinx API 如果已打模块,则不需要这个类
$sphinx = new SphinxClient();
#创建sphinx对象
$sphinx->SetServer("localhost", 9312);
#建立连接,第一个参数sphinx服务器地址,第二个sphinx监听端口
$keyword= ‘兄弟连‘;
$sphinx->setMatchMode(SPH_MATCH_ANY); #匹配模式
$result = $sphinx->query($keyword,"*");
#执行查询,第一个参数查询的关键字,第二个查询的索引名称,多个索引名称用,分开,也可以用*表示全部索引,其中包括增量索引
echo ‘<pre>‘;
var_dump($result);#打印结果
找到下面这一段,是我匹配的数据
[matches] => Array ( //匹配的结果
[6] => 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 一共出现多少次
[连] => Array
[docs] => 2
[hits] => 6
(3)、取得数据摘要并高亮显示
Matches中就是我们匹配的结果,但是仿佛不是我们想要的数据,比如 titile,content字段的内容就没有匹配出来,根据官方的说明是 Sphinx 并没有连接到 MySQL去取数据,只是根据它自己的索引内容进行计算,因此如果想用 Sphinx 提供的API 去取得我们想要的数据,还必须以查询的结果为依据,再次查询 MySQL从而得到我们想要的数据
比如:
$mysqli = new mysqli("localhost","root","password","test");
$ids= join(‘,‘,array_keys($result[‘matches‘])); 要把需要的id取出来。
$sql="select title,content from post where id in({$ids})”;
$result=$mysqli->query($sql);
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>"; 添加时间
}
#循环体结束
到这里呢,我们用php程序调用sphinxapi实现了高亮摘要功能
三、匹配模式
匹配模式: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(id INT PRIMARY KEY, max_doc_id INT);
2、再次修改配置文件
主数据源,继承数据源,主索引,继承索引。(继承索引也就是增量索引)。
主数据源里面:我们需要把欲查询语句改成下面的语句:
vi /usr/local/coreseek/etc/csft.conf
主数据源
Source main{
#添加一个sql_query_pre语句
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM post
#修改sql_query内容如下
sql_query= \
SELECT id,title, content FROM post \
WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
}
增量数据源,继承自main数据源,只需要重写main中的sql_query_pre和sql_query项,
并将默认的test1stemmed名字改为delta方便管理
增量数据源
source delta : main
{
sql_query_pre = SET NAMES utf8
sql_query= \
SELECT id,title, content FROM post \
WHERE id>(SELECT max_doc_id FROM sph_counter WHERE id=1)
}
主索引不变
Index ind_main {
source = main
path = /usr/local/coreseek/var/data/main
}
增量索引,继承了ind_main索引,并重写source和path项
index ind_delta:ind_main
{
source= delta
path= /usr/local/coreseek/var/data/ind_delta
# distributed index
}
其它配置不用改变
注意:如果你增量索引的 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、测试增量索引+主索引
如果想测试增量索引是否成功,往数据库表中插入数据,查找是否能够检索到,这个时候检索应该为空,然后,单独重建增量索引
INSERT INTO post (title,content) VALUES (‘管长龙的邮箱‘,‘管长龙guanchanglong email : [email protected] lamp兄弟连‘);
/usr/local/coreseek/bin
./search email #检索没有结果
./indexer ind_delta #做增量索引,查看是否将新的记录进行了索引
ls /usr/local/coreseek/var/data/
./search email #再次测试,就可以检索出来了
此时,再用/usr/local/coreseek/bin/search 工具来检索,能够看到,在主索引中检索到的结果为 0,而在增量中检索到结果。当然,前提条件是,检索的词,只在后来插入的数据中存在
4、实时更新索引
我们需要建立两个脚本,还要用到计划任务
建立一个主索引和增量索引的脚本
main.sh delta.sh
在增量索引中写下delta.sh
vi /usr/local/coreseek/etc/delta.sh
#!/bin/bash
#delta.sh
/usr/local/coreseek/bin/indexer ind_delta --rotate >>/usr/local/coreseek/var/log/delta.log
主索引中写下:main.sh
vi /usr/local/coreseek/etc/main.sh
#!/bin/bash
#main.sh
/usr/local/coreseek/bin/indexer ind_main --rotate >>/usr/local/coreseek/var/log/main.log
最后,我们需要脚本能够自动运行,以实现增量索引每5分钟重新建立,和主索引只在凌晨2:30时重新建立.
脚本写好了,我们需要建立计划任务
crontab -e
*/5 * * * * /usr/local/coreseek/etc/delta.sh
30 2 * * * /usr/local/coreseek/etc/main.sh
第一条是表示每5分钟运行
第二条是表示每天的凌晨2:30分运行
脚本权限:
chmod a+x /usr/local/coreseek/etc/delta.sh
chmod a+x /usr/local/coreseek/etc/main.sh
要验证的话,我们可以查看日志文件
五、分布式索引(了解)
分布式是为了改善查询延迟问题和提高多服务器、多 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 远程
}
Sphinx我们已经基本讲完,主要讲解了包括 Sphinx、中文分词、高亮、摘要、匹配、增量索引、实时索引和分布式索引等方面的知识.
六.PHP代码实例:
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sphinx搜索测试</title>
</head>
<body>
<h3>Sphinx搜索测试</h3>
<form action="find.php" method="get">
<span>请输入搜索关键字</span>
<input type="text" name="keyword">
<input type="submit">
</form>
</body>
</html>
find.php
<?php
/**
* Sphinx演示代码
* @author ZouYiliang <[email protected]>
*/
header(‘Content-Type:text/html;charset=utf-8‘);
//include ‘sphinxapi.php‘;
$keyword=$_GET[‘keyword‘];
//实例化对象
$sphinx=new SphinxClient();
//设置服务器信息
$sphinx->SetServer(‘localhost‘,9312);
//设置全文查询的匹配模式
$sphinx->SetMatchMode(SPH_MATCH_ANY); //例:lamp php则文档中有任意一个个单词就能匹配该文档
//$sphinx->SetMatchMode(SPH_MATCH_ALL); //例:lamp php则文档中必须同时出现这两个单词
//设置返回结果集偏移量和数目
$sphinx->setLimits(0,2);
//执行搜索查询
$result=$sphinx->query($keyword,‘*‘);//第二个参数是指定使用哪一个索引,例如ind_main
/*
echo "<pre>";
print_r($result);
exit;
//*/
/*
"matches" 存储文档ID以及其对应的另一个包含文档权重和属性值的hash表
"total" 此查询在服务器检索所得的匹配文档总数(即服务器端结果集的大小,且与相关设置有关)
"total_found" (服务器上找到和处理了的)索引中匹配文档的总数
"words" 将查询关键字(关键字已经过大小写转换,取词干和其他处理)
包含关于关键字的统计数据
docs——在多少文档中出现
hits——共出现了多少次)
"error" searchd报告的错误信息
"warning" searchd报告的警告信息
$result[‘matches‘]中的key,就是post表的id
*/
if($result[‘total_found‘]==0){
echo ‘查无结果‘;
exit;
}else{
echo "共查到 {$result[‘total_found‘]} 条记录<hr>";
}
//拿到所有的id,用逗号组装,用于sql中的in查询
if(is_array($result[‘matches‘])){
$ids=join(‘,‘,array_keys($result[‘matches‘]));
}
//连接MySQL数据库
mysql_connect(‘localhost‘,‘root‘,‘root‘);
mysql_query(‘set names utf8‘);
mysql_select_db(‘test‘);
//根据id从数据库中查询数据,存放到$posts变量中
$posts=array();
$sql="select * from post where id in({$ids})";
$rst=mysql_query($sql);
if($rst && mysql_num_rows($rst)>0){
while ($row=mysql_fetch_assoc($rst)) {
$posts[]=$row;
}
}
//var_dump($posts);
//高亮显示的模板
$opts=array(
"before_match"=>"<span style=‘font-weight:bold;color:red‘>",
"after_match"=>"</span>"
);
foreach($posts as $row){
$item=$sphinx->buildExcerpts($row,"ind_main",$keyword,$opts);
//用索引访问
echo "编号: {$item[0]}<br>";
echo "标题: {$item[1]}<br>";
echo "内容: {$item[2]}<br>";
echo "<hr>";
}
//sphin配置介绍
http://www.php100.com/html/itnews/it/2013/0505/13435.html
//相关文档介绍
http://blog.csdn.net/aidandai/article/details/50464793
http://www.keyunq.com/server/coreseek-sphinx.html
http://blog.csdn.net/u011247211/article/details/16841337
//win7下安装
http://doc.okbase.net/strick/archive/119784.html
//thinkphp 配置方法
http://bbs.lampbrother.net/read-htm-tid-162848.html