Home > 一点点积累 > Database

Database Archive

全文检索之Sphinx速成指南

1. Sphinx简介


1.1. 什么是全文检索
全文检索是指以文档的全部文本信息作为检索对象的一种信息检索技术。检索的对象有可能是文章的标题,也有可能是文章的作者,也有可能是文章摘要或内容。

1.2. 介绍
Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。

1.3. Sphinx的特性
高速索引 (在新款CPU上,近10 MB/秒);
高速搜索 (2-4G的文本量中平均查询速度不到0.1秒);
高可用性 (单CPU上最大可支持100 GB的文本,100M文档);
提供良好的相关性排名
支持分布式搜索;
提供文档摘要生成;
提供从MySQL内部的插件式存储引擎上搜索
supports boolean, phrase, and word proximity queries;
支持每个文档多个全文检索域(默认最大32个);
支持每个文档多属性;
支持断词;
支持单字节编码与UTF-8编码;
supports English stemming, Russian stemming, and Soundex for morphology;
支持MySQ(MyISAM和InnoDB 表都支持);
支持PostgreSQL.
 

2. Sphinx安装(For MySQL)
2.1. Windows下安装
http://dev.mysql.com上下载MySQL5.0.45版安装配置好MySQL,采用utf-8字符集
从Sphinx官网上http://www.sphinxsearch.com/downloads.html下载mysql-5.0.45-sphinxse-r871-win32.zip和sphinx-0.9.8-svn-r985-win32.zip
如果您的MySQL服务已启动请先停止掉
解压mysql-5.0.45-sphinxse-r871-win32.zip,将里面bin与share目录覆盖掉你的mysql安装目录下的相应目录
解压sphinx-0.9.8-svn-r985-win32.zip ,将里面的文件解压到D:\sphinx
sphinx的配置与实际应用是相关的,因此以下我以例子进行说明,至此sphinx安装部分结束
2.2. Linux下安装
下载mysql-5.1.22-rc.tar.gz解压至/root/mysql-5.1.22
下载sphinx-0.9.8-svn-r985.tar.gz,解压至/root/sphinx-0.9.8-svn-r985
将/root/sphinx-0.9.8-svn-r985/mysqlse下的文件复制至/root/mysql-5.1.22/storage/sphinx
在/root/mysql-5.1.22目录下运行 

CODE:
  1. sh BUILD/autorun.sh
  2. ./configure --prefix=/usr/local/mysql --with-charset=utf8 --with-extra-charsets=all \
  3. --enable-thread-safe-client --enable-assembler --with-readline --with-big-tables \
  4. --with-plugins=sphinx
  5. make && make install
  6. groupadd mysql
  7. useradd –g mysql mysql
  8. chown mysql:mysql /usr/local/mysql -R
  9. cd /usr/local/mysql
  10. bin/mysql_install_db –user=mysql
  11. (此时系统可能会提示:
  12. [Warning] Storage engine 'SPHINX' has conflicting typecode. Assigning value 42.
  13. 可忽略,不影响使用)
  14. cp /root/mysql-5.1.22/support-files/mysql.server /etc/init.d/mysqld
  15. chmod 700 /etc/init.d/mysqld
  16. cp /root/mysql-5.1.22/support-files/my-medium.cnf /etc/my.cnf
  17. /etc/init.d/mysql start
  18. (至些mysql启动了)

然后进入mysql命令行,运行show engines,看是不是有一个叫sphinx的engine,有的话就表示sphinxSE(mysql的sphinx引擎)安装正常了
进入/root/sphinx-0.9.8-svn-r985,运行 

CODE:
  1. ldconfig /usr/local/mysql/lib/mysql
  2. ldconfig /usr/local/mysql/include/mysql
  3. ./configure --prefix=/usr/local/sphinx --with-mysql=/usr/local/mysql
  4. make && make install

 

3. 实例说明
为更好说明如何应用Sphinx,现结合实例说明,我们以网站的新闻文章表为例。我们想要对新闻文章表进行全文检索(主要是标题与内容),新闻文章表的相关信息如下:

 

SQL:
  1. CREATE TABLE `eht_articles` (
  2.   `ARTICLESID` int(11) NOT NULL AUTO_INCREMENT,
  3.   `TITLE` varchar(100) NOT NULL DEFAULT '',
  4.   `TITLECOLOR` varchar(20) DEFAULT NULL,
  5.   `AUTHOR` varchar(200) DEFAULT NULL,
  6.   `COMEFROM` varchar(200) DEFAULT NULL,
  7.   `KEYWORD` varchar(200) DEFAULT NULL,
  8.   `HTMLURL` varchar(200) DEFAULT NULL,
  9.   `CATALOGID` int(6) DEFAULT NULL,
  10.   `CONTENTS` mediumtext,
  11.   `EDITUSERID` int(6) DEFAULT NULL,
  12.   `ADDTIME` int(10) DEFAULT NULL,
  13.   `UPDATETIME` int(10) DEFAULT NULL,
  14.   `HITS` int(6) DEFAULT NULL,
  15.   PRIMARY KEY (`ARTICLESID`)
  16. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

在这个表中,我主要想对标题(TITLE)与内容(CONTENTS)字段进行全文检索,在检索过程中可能我会根据文章的栏目(CATALOGID),编辑(EDITUSERID),时间段(ADDTIME)进行条件性的全文检索,然后可能会根据主键ID(ARTICLESID),人气(HITS)进行排序显示,如何配置Sphinx来实现呢?

4. Sphinx配置
sphinx是以sphinx.conf为配置文件,索引与搜索均以这个文件为依据进行,要进行全文检索,首先就要配置好sphinx.conf,告诉sphinx哪些字段需要进行索引,哪些字段需要在where,orderby,groupby中用到。

安装完Sphinx后,在D:/sphinx目录有一个sphinx.conf.in,这个相当于sphinx的配置例子文件,我们以这个文件为蓝本,重新创建一个空白内容的sphinx.conf,存放在d:/sphinx根目录。
sphinx.conf的内容组成 

source 源名称1{

}
index 索引名称1{
source=源名称1

}
source 源名称2{

}
index 索引名称2{
source = 源名称2

}
indexer{

}
searchd{

}

提示:从组成我们可以发现sphinx可以定义多个索引与数据源,不同的索引与数据源可以应用到不同表或不同应用的全文检索。

根据前面的实例,我们配置出我们需要的sphinx.conf,如下: 

CODE:
  1. source cgfinal
  2. {
  3.  type = mysql
  4.  strip_html = 0
  5.  index_html_attrs =
  6.  sql_host = localhost
  7.  sql_user = root
  8.  sql_pass = admin
  9.  sql_db = test
  10.  sql_port= 3306 # optional, default is 3306
  11.  sql_query_pre=  SET NAMES utf8
  12.  
  13.  sql_query = SELECT ARTICLESID,TITLE,CONTENTS,AUTHOR,CATALOGID,ADDTIME,EDITUSERID,\
  14. HITS FROM a.eht_news_articles
  15.  #sql_query = SELECT * FROM a.eht_news_articles
  16.  sql_attr_uint= CATALOGID
  17.  sql_attr_uint= EDITUSERID
  18.  sql_attr_uint = HITS
  19.  sql_attr_timestamp = ADDTIME
  20.  
  21.  sql_query_post  =
  22.  sql_ranged_throttle= 0
  23.  #sql_query_info = SELECT * FROM a.eht_news_articles WHERE ARTICLESID=$id
  24. }
  25. index cgfinal
  26. {
  27.  source   = cgfinal
  28.  path   = d:/sphinx/data/cgfinal
  29.  docinfo   = extern
  30.  mlock   = 0
  31.  morphology   = none
  32.  stopwords   =
  33.  min_word_len  = 1
  34.  charset_type  = utf-8
  35.  charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z,\
  36. A..Z->a..z, a..z, U+0149, U+017F, U+0138, U+00DF, U+00FF, U+00C0..U+00D6->U+00E0..U+00F6,\
  37. U+00E0..U+00F6, U+00D8..U+00DE->U+00F8..U+00FE, U+00F8..U+00FE, U+0100->U+0101, U+0101,\
  38. U+0102->U+0103, U+0103, U+0104->U+0105, U+0105, U+0106->U+0107, U+0107, U+0108->U+0109,\
  39. U+0109, U+010A->U+010B, U+010B, U+010C->U+010D, U+010D, U+010E->U+010F, U+010F,\
  40. U+0110->U+0111, U+0111, U+0112->U+0113, U+0113, U+0114->U+0115, U+0115, \
  41. U+0116->U+0117,U+0117, U+0118->U+0119, U+0119, U+011A->U+011B, U+011B, U+011C->U+011D,\
  42.  U+011D,U+011E->U+011F, U+011F, U+0130->U+0131, U+0131, U+0132->U+0133, U+0133, \
  43. U+0134->U+0135,U+0135, U+0136->U+0137, U+0137, U+0139->U+013A, U+013A, U+013B->U+013C, \
  44. U+013C,U+013D->U+013E, U+013E, U+013F->U+0140, U+0140, U+0141->U+0142, U+0142, \
  45. U+0143->U+0144,U+0144, U+0145->U+0146, U+0146, U+0147->U+0148, U+0148, U+014A->U+014B, \
  46. U+014B,U+014C->U+014D, U+014D, U+014E->U+014F, U+014F, U+0150->U+0151, U+0151, \
  47. U+0152->U+0153,U+0153, U+0154->U+0155, U+0155, U+0156->U+0157, U+0157, U+0158->U+0159,\
  48.  U+0159,U+015A->U+015B, U+015B, U+015C->U+015D, U+015D, U+015E->U+015F, U+015F, \
  49. U+0160->U+0161,U+0161, U+0162->U+0163, U+0163, U+0164->U+0165, U+0165, U+0166->U+0167, \
  50. U+0167,U+0168->U+0169, U+0169, U+016A->U+016B, U+016B, U+016C->U+016D, U+016D, \
  51. U+016E->U+016F,U+016F, U+0170->U+0171, U+0171, U+0172->U+0173, U+0173, U+0174->U+0175,\
  52.  U+0175,U+0176->U+0177, U+0177, U+0178->U+00FF, U+00FF, U+0179->U+017A, U+017A, \
  53. U+017B->U+017C,U+017C, U+017D->U+017E, U+017E, U+0410..U+042F->U+0430..U+044F, \
  54. U+0430..U+044F,U+05D0..U+05EA, U+0531..U+0556->U+0561..U+0586, U+0561..U+0587, \
  55. U+0621..U+063A, U+01B9,U+01BF, U+0640..U+064A, U+0660..U+0669, U+066E, U+066F, \
  56. U+0671..U+06D3, U+06F0..U+06FF,U+0904..U+0939, U+0958..U+095F, U+0960..U+0963, \
  57. U+0966..U+096F, U+097B..U+097F,U+0985..U+09B9, U+09CE, U+09DC..U+09E3, U+09E6..U+09EF, \
  58. U+0A05..U+0A39, U+0A59..U+0A5E,U+0A66..U+0A6F, U+0A85..U+0AB9, U+0AE0..U+0AE3, \
  59. U+0AE6..U+0AEF, U+0B05..U+0B39,U+0B5C..U+0B61, U+0B66..U+0B6F, U+0B71, U+0B85..U+0BB9, \
  60. U+0BE6..U+0BF2, U+0C05..U+0C39,U+0C66..U+0C6F, U+0C85..U+0CB9, U+0CDE..U+0CE3, \
  61. U+0CE6..U+0CEF, U+0D05..U+0D39, U+0D60,U+0D61, U+0D66..U+0D6F, U+0D85..U+0DC6, \
  62. U+1900..U+1938, U+1946..U+194F, U+A800..U+A805,U+A807..U+A822, U+0386->U+03B1, \
  63. U+03AC->U+03B1, U+0388->U+03B5, U+03AD->U+03B5,U+0389->U+03B7, U+03AE->U+03B7, \
  64. U+038A->U+03B9, U+0390->U+03B9, U+03AA->U+03B9,U+03AF->U+03B9, U+03CA->U+03B9, \
  65. U+038C->U+03BF, U+03CC->U+03BF, U+038E->U+03C5,U+03AB->U+03C5, U+03B0->U+03C5, \
  66. U+03CB->U+03C5, U+03CD->U+03C5, U+038F->U+03C9,U+03CE->U+03C9, U+03C2->U+03C3, \
  67. U+0391..U+03A1->U+03B1..U+03C1,U+03A3..U+03A9->U+03C3..U+03C9, U+03B1..U+03C1, \
  68. U+03C3..U+03C9, U+0E01..U+0E2E,U+0E30..U+0E3A, U+0E40..U+0E45, U+0E47, U+0E50..U+0E59, \
  69. U+A000..U+A48F, U+4E00..U+9FBF,U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF, \
  70. U+2F800..U+2FA1F, U+2E80..U+2EFF,U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF, \
  71. U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF, \
  72. U+3130..U+318F, U+A000..U+A48F,U+A490..U+A4CF
  73.  min_prefix_len  = 0
  74.  min_infix_len  = 1
  75.  ngram_len = 1
  76.  
  77.  ngrams_chars = U+4E00..U+9FBF, U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF,\
  78. U+2F800..U+2FA1F, U+2E80..U+2EFF, U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF,\
  79. U+3040..U+309F, U+30A0..U+30FF, U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF,\
  80. U+3130..U+318F, U+A000..U+A48F, U+A490..U+A4CF
  81. }
  82. indexer
  83. {
  84.  mem_limit   = 32M
  85. }
  86. searchd
  87. {
  88.  # address    = 0.0.0.0
  89.  port    = 3312
  90.  log     = d:/sphinx/log/searchd.log
  91.  query_log   = d:/sphinx/log/query.log
  92.  read_timeout  = 5
  93.  max_children  = 30
  94.  pid_file   = d:/sphinx/log/searchd.pid
  95.  max_matches   = 1000
  96.  seamless_rotate  = 1
  97. }

相关配置项说明: 
Source部分配置项说明 
#type 数据库类型,目前支持mysql与pgsql
#strip_html 是否去掉html标签
#sql_host 数据库主机地址
#sql_user 数据库用户名
#sql_pass 数据库密码
#sql_db 数据库名称
#sql_port 数据库采用的端口
#sql_query_pre 执行sql前要设置的字符集,用utf8必须SET NAMES utf8
#sql_query 全文检索要显示的内容,在这里尽可能不使用where或group by,将where与
 groupby的内容交给sphinx,由sphinx进行条件过滤与groupby效率会更高
#注意:select 出来的字段必须至少包括一个唯一主键(ARTICLESID)以及要全文检索的
  字段,你计划原本在where中要用到的字段也要select出来
#这里不用使用orderby
#sql_attr_开头的表示一些属性字段,你原计划要用在where,orderby,groupby中的字段要
 在这里定义
#根据我们原先的SQL:

SQL:
  1. #select * from eht_articles where title like ? and catalogid=? And edituserid=? \
  2. AND addtime BETWEEN ? AND ? ORDER BY hits DESC

#我们需要对catalogid,edituserid,addtime,hits进行属性定义(这四个字段也要在select的
字段列表中),定义时不同的字段类型有不同的属性名称,具体可以见sphinx.conf.in中的说明

index部分配置项说明 
#source 数据源名
#path 索引记录存放目录,如d:/sphinx/data/cgfinal,实际存放时会存放在d:/sphinx/data目
录,然后创建多个cgfinal名称,不同扩展名的索引文件。
#其他的配置如min_word_len,charset_type,charset_table,ngrams_chars,ngram_len这些则是支
持中文检索需要设置的内容。
#如果检索的不是中文,则charset_table,ngrams_chars,min_word_len就要设置不同的内容,具
体官方网站的论坛中有很多,大家可以去搜索看看。

5. 运行Sphinx
 

首先要对数据进行索引或重建索引 
进入命令行,运行d:/sphinx/bin/release/indexer --config d:/sphinx/sphinx.conf cgfinal
如果您在sphinx.conf中配置了多个数据源,想一次性全部索引则d:/sphinx/bin/release/indexer --config d:/sphinx/sphinx.conf --all
如果只是想对某个数据源进行索引,则d:/sphinx/bin/release/indexer --config d:/sphinx/sphinx.conf 索引名称(这里的索引名称是你在sphinx.conf中定义的索引名称)
 

运行检索守护进程searchd进入命令行,运行d:/sphinx/bin/release/searchd --config d:/sphinx/sphinx.conf,此时系统会在3312端口侦听mysql的全文检索请求,所以如果您的mysql与sphinx不在同一台机器,要保证3312端口不被防火墙阻隔。
 

6. 搜索(翻译)


6.1. 匹配模式

 

SPH_MATCH_ALL,匹配所有查询词(缺省模式)
SPH_MATCH_ANY,匹配任意查询词
SPH_MATCH_PHRASE,短语匹配
SPH_MATCH_BOOLEAN,布尔表达式匹配
SPH_MATCH_EXTENDED,查询匹配一个Sphinx内部查询语言表达式
 

6.2. 布尔查询语法(Boolean query syntax)
布尔查询允许使用下面特殊操作符:

AND:hello & world
OR:hello | world
NOT:hello -world或hello !world
Grouping:(hello world)
举一个使用这些操作符的例子:

( cat -dog ) | ( cat -mouse)

AND是一个隐式操作符,“hello world”就相当于“hello & world”。

OR的优先级高于AND,所以“looking for cat | dog | mouse”的意思是“looking for (cat | dog | mouse)”而不是“(looking for cat) | dog | mouse”

象“-dog”这种隐式地包含了所有查询记录,是不会被执行的。这主要是考虑到技术上与性能上的原因,从技术上来说,sphinx不能总保持所有文章的ID列表,性能上来说,当结果集巨大(10-100M),执行这样的查询将费耗较长时间。

6.3. 扩展查询语法(Extended query syntax)
扩展查询允许合我下面特殊操作符:

操作符OR:hello | world
操作符NOT:hello -world或hello !world
字段搜索操作符:@title hello @body world
短语(phrase)搜索符:"hello world"
临近(proximity)搜索符:"hello world"~10
举例:

"hello world" @title "example program"~5 @body python -(php|perl)

AND是一个隐式操作符,"hello world"表示hello与world都要出现在匹配的记录中。

OR的优先级高于AND,所以“looking for cat | dog | mouse”的意思是“looking for (cat | dog | mouse)”而不是“(looking for cat) | dog | mouse”

临近距离在串中标明了,主要是用来调整单词数量,应用在引号中的所有查询字串。"cat dog mouse"~5表示包括这三个单词在内,总共不能多于8个单词的间隔。比如"CAT aaa bbb ccc DOG eee fff MOUSE"就不能匹配这个查询,因为单词间隔刚好是8个。

象aaa | ( bbb ccc | ( ddd eee ) )这样的括号嵌套查询目前还不支持,但以后会修正的。

否定(如NOT)只允许出现在顶层,不允许出现在括号内(如groups)。这点是不会改变的。因为支持否定嵌套查询会让短语排序(phrase ranking)的实现变得过于复杂。

6.4. 权重(匹配度,Weight)
采用什么权重功能取决于搜索模式(Search mode)

在权重函数中,有两个主要部分:(短语排名)phrase rank和statistical rank(统计排名)

短语排名是基于搜索词在文档和查询短语中的最长公共子序列(LCS)的长度。所以如果在记录中有切确的短语匹配,记录的短语排名将有可能是最高的,等于查询单词的总个数。

统计排名是建立在经典的BM25算法基础之上,它只考虑词频。词在全部文档集合中以低的频度出现或高频度出现在匹配的文档中,那么它获得的权重就越大,最终的BM25权重是一个介于0到1之间的小数。

好的子短语匹配得到好的排名,最好的匹配放到最顶端。Sphinx作者的经验是:基于排名的密切短语比其它任何单独的统计方式表现出较好的搜索质量。

在SPH_MATCH_BOOLEAN 模式中,不需要计算权重,每条匹配记录的权重都是1

在SPH_MATCH_ALL和SPH_MATCH_PHRASE模式中,最终的权重是短语排名权重的总和

(TOFIX:翻译不畅)在SPH_MATCH_ANY模式中,本质上是一样的,但它也增加了每个字段的匹配单词数量,在这之前,短语排名权重乘以一个足够大的值以保证在任意一个字段的较高短语排名可以匹配排名较高者,即使它的字段权重比较低。

在SPH_MATCH_EXTENDED模式中,最终的权重是短语权重和BM25权重的总和,再乘以1000取整。

7. 如何调用Sphinx
按上面配置,第5节点对数据库进行了索引,通过Sphinx自带的search(在bin/release目录)就可以在命令行进行搜索:

 

CODE:
  1. (搜索CGArt)
  2. windows上:
  3. search -c d:/sphinx/sphinx.conf CGArt
  4. Linux上:
  5. cd /usr/local/sphinx
  6. ./bin/search -c sphinx.conf CGArt
  7. 运行后,系统提示一堆信息:
  8. ....
  9. ....
  10. words:
  11. 1. 'cgart': 36 documents, 189 hits
  12. 这个表示库中有36条记录符合要求,出现CGArt的有189处。

应用程序如果想调用Sphinx,可以从两个方面:

一是通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本)
二是通过安装SphinxSE(具体见1.2部分),然后创建一个中介sphinxSE类型的表,再通过执行特定的SQL语句实现。
通过官方API调用Sphinx(以PHP为例)在sphinx安装目录有一个API目录,里面有三个PHP文件:test.php,test2.php和sphinxapi.php。sphinxapi.php是sphinx调用接口封装文件,test.php是一个在命令行下执行的查询例子文件,test2.php是一个生成摘要的例子文件。
在命令下行运行test.php(Linux上没有API目录,需要从源程序包中复制api目录至/usr/local/sphinx)

CODE:
  1. Windows上:
  2. D:\sphinx\bin\release>c:\php5.2\php.exe -c c:\php5.2\php.ini ..\..\api\test.php -i cgfinal CGart
  3. Linux上(php在/usr/local/php目录,sphinx.conf在/usr/local/sphinx目录)
  4. cd /usr/local/sphinx
  5. /usr/local/php/bin/php api/test.php -i cgfinal CGArt

Sphinx的API查询接口主要有这些内容(其实对照 一下sphinxapi.php就清楚了):

PHP:
  1. //创建Sphinx的客户端接口对象
  2. $cl = new SphinxClient ();
  3.  
  4. //设置连接Sphinx主机名与端口
  5. $cl->SetServer('localhost',3312);
  6.  
  7. //可选,为每一个全文检索字段设置权重,主要根据你在sql_query中定义的字段的顺序,Sphinx系统以后会调整,可以按字段名称来设定权重
  8. $cl->SetWeights ( array ( 100, 1 ) );
  9.  
  10. //设定搜索模式,SPH_MATCH_ALL,SPH_MATCH_ANY,SPH_MATCH_BOOLEAN,SPH_MATCH_EXTENDED,SPH_MATCH_PHRASE
  11. $cl->SetMatchMode(SPH_MATCH_ALL);
  12.  
  13. //设定过滤条件$attribute是属性名,相当于字段名(用SPH_MATCH_EXTENDED时),$value是值,$exclude是布尔型,
  14. 当为true时,相当于$attribute!=$value,默认值是false
  15. $cl->SetFilter($attribute, $values, $exclude);
  16.  
  17. //设定group by
  18. //根据分组方法,匹配的记录集被分流到不同的组,每个组都记录着组的匹配记录数以及根据当前排序方法本组中的最佳匹配记录。
  19. //最后的结果集包含各组的一个最佳匹配记录,和匹配数量以及分组函数值
  20. //结果集分组可以采用任意一个排序语句,包括文档的属性以及sphinx的下面几个内部属性
  21. //@id--匹配文档ID
  22. //@weight, @rank, @relevance--匹配权重
  23. //@group--group by 函数值
  24. //@count--组内记录数量
  25. //$groupsort的默认排序方法是@group desc,就是按分组函数值大小倒序排列
  26. $cl->SetGroupBy($attribute, $func, $groupsort);
  27.  
  28. //设定order by的内容,第一个参数是排序方法名,值有
  29. // SPH_SORT_RELEVANCE,SPH_SORT_ATTR_DESC,SPH_SORT_ATTR_ASC,SPH_SORT_TIME_SEGMENTS,SPH_SORT_EXTENDED
  30. //$sortby的值如"HITS desc"
  31. $cl->SetSortMode(SPH_SORT_EXTENDED, $sortby);
  32.  
  33. //set count-distinct attribute for group-by queries,$distinct为字符串
  34. $cl->SetGroupDistinct ( $distinct );
  35.  
  36. //相当于mysql的limit $offset,$limit
  37. $cl->SetLimits($start,$limit)
  38.  
  39. //$q是查询的关键字,$index是索引名称,当等于*时表查询所有索引
  40. $res = $cl->Query ( $q, $index );

$cl->Query()返回的内容print_r后大概是:

CODE:
  1. Array
  2. (
  3.     [error] =>
  4.     [warning] =>
  5.     [status] => 0
  6.     [fields] => Array
  7.         (
  8.             [0] => title
  9.             [1] => contents
  10.             [2] => author
  11.         )
  12.  
  13.     [attrs] => Array
  14.         (
  15.             [catalogid] => 1
  16.             [addtime] => 2
  17.             [edituserid] => 1
  18.             [hits] => 1
  19.         )
  20.  
  21.     [matches] => Array
  22.         (
  23.             [380] => Array
  24.                 (
  25.                     [weight] => 1
  26.                     [attrs] => Array
  27.                         (
  28.                             [catalogid] => 7
  29.                             [addtime] => 1112677492
  30.                             [edituserid] => 1
  31.                             [hits] => 1470
  32.                         )
  33.  
  34.                 )
  35.  
  36.             [599] => Array
  37.                 (
  38.                     [weight] => 101
  39.                     [attrs] => Array
  40.                         (
  41.                             [catalogid] => 7
  42.                             [addtime] => 1115910729
  43.                             [edituserid] => 1
  44.                             [hits] => 1749
  45.                         )
  46.  
  47.                 )
  48.  
  49.             [850] => Array
  50.                 (
  51.                     [weight] => 1
  52.                     [attrs] => Array
  53.                         (
  54.                             [catalogid] => 2
  55.                             [addtime] => 1118741392
  56.                             [edituserid] => 1
  57.                             [hits] => 289
  58.                         )
  59.  
  60.                 )
  61.  
  62.             [877] => Array
  63.                 (
  64.                     [weight] => 1
  65.                     [attrs] => Array
  66.                         (
  67.                             [catalogid] => 2
  68.                             [addtime] => 1118898869
  69.                             [edituserid] => 1
  70.                             [hits] => 9870
  71.                         )
  72.  
  73.                 )
  74.  
  75.             [1040] => Array
  76.                 (
  77.                     [weight] => 101
  78.                     [attrs] => Array
  79.                         (
  80.                             [catalogid] => 2
  81.                             [addtime] => 1120708579
  82.                             [edituserid] => 1
  83.                             [hits] => 318
  84.                         )
  85.  
  86.                 )
  87.  
  88.         )
  89.  
  90.     [total] => 129
  91.     [total_found] => 129
  92.     [time] => 0.000
  93.     [words] => Array
  94.         (
  95.             [design] => Array
  96.                 (
  97.                     [docs] => 129
  98.                     [hits] => 265
  99.                 )
  100.  
  101.         )
  102.  
  103. )

从上面可以看出Query并不能全部取得我们想要的记录内容,比如说Title,Contents字段就没有取出来,根据官方的说明是sphinx并没有连到mysql去取记录,只是根据它自己的索引内容进行计算,因此如果想用sphinxAPI去取得我们想要的记录,还必须将Query的结果为依据去查询MySQL才可以得到最终我们想要的结果集。

test2.php是一个摘要生成的例子文件,如果你的本地机器已装好sphinx,php运行环境,你可以通过浏览器看查看test2.php的运行效果。

假设我要搜索关键词"test",通过sphinx可以取到搜索结果,在显示搜索结果时,我希望将含有"test"的进行红色或加粗显示,同时,我不希望全部都显示出来,只需要显示一段摘要,就象google或百度那样,搜出来的结果不是全篇显示,只是部分显示,这个就是摘要的作用。

以test2.php中为例,以下是test2.php的代码:

PHP:
  1. <?php
  2. require ( "sphinxapi.php" );