如何调用Sphinx

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

来源:http://hi.baidu.com/ndlli/blog/item/cef79419e082a74b43a9ad93.html

(搜索CGArt)
windows上:
search -c d:/sphinx/sphinx.conf CGArt
Linux上:
cd /usr/local/sphinx
./bin/search -c sphinx.conf CGArt
运行后,系统提示一堆信息:
....
....
words:
1. 'cgart': 36 documents, 189 hits
这个表示库中有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)

Windows上:
D:\sphinx\bin\release>c:\php5.2\php.exe -c c:\php5.2\php.ini ..\..\api\test.php -i cgfinal CGartLinux上(php在/usr/local/php目录,sphinx.conf在/usr/local/sphinx目录):

cd /usr/local/sphinx
/usr/local/php/bin/php api/test.php -i cgfinal CGArtSphinx的API查询接口主要有这些内容(其实对照 一下sphinxapi.php就清楚了):

//创建Sphinx的客户端接口对象
   $cl = new SphinxClient ();

//设置连接Sphinx主机名与端口
   $cl->SetServer('localhost',3312);

//可选,为每一个全文检索字段设置权重,主要根据你在sql_query中定义的字段的顺序,Sphinx系统以后会调整,可以按字段名称来设定权重
   $cl->SetWeights ( array ( 100, 1 ) );

//设定搜索模式,SPH_MATCH_ALL,SPH_MATCH_ANY,SPH_MATCH_BOOLEAN,SPH_MATCH_EXTENDED,SPH_MATCH_PHRASE
   $cl->SetMatchMode(SPH_MATCH_ALL);

//设定过滤条件$attribute是属性名,相当于字段名(用SPH_MATCH_EXTENDED时),$value是值,$exclude是布尔型,
   当为true时,相当于$attribute!=$value,默认值是false
   $cl->SetFilter($attribute, $values, $exclude);

//设定group by
   //根据分组方法,匹配的记录集被分流到不同的组,每个组都记录着组的匹配记录数以及根据当前排序方法本组中的最佳匹配记录。
   //最后的结果集包含各组的一个最佳匹配记录,和匹配数量以及分组函数值
   //结果集分组可以采用任意一个排序语句,包括文档的属性以及sphinx的下面几个内部属性
   //@id--匹配文档ID
   //@weight, @rank, @relevance--匹配权重
   //@group--group by 函数值
   //@count--组内记录数量
   //$groupsort的默认排序方法是@group desc,就是按分组函数值大小倒序排列
   $cl->SetGroupBy($attribute, $func, $groupsort);

//设定order by的内容,第一个参数是排序方法名,值有
   // SPH_SORT_RELEVANCE,SPH_SORT_ATTR_DESC,SPH_SORT_ATTR_ASC,SPH_SORT_TIME_SEGMENTS,SPH_SORT_EXTENDED
   //$sortby的值如"HITS desc"
   $cl->SetSortMode(SPH_SORT_EXTENDED, $sortby);

//set count-distinct attribute for group-by queries,$distinct为字符串
   $cl->SetGroupDistinct ( $distinct );

//相当于mysql的limit $offset,$limit
   $cl->SetLimits($start,$limit)

//$q是查询的关键字,$index是索引名称,当等于*时表查询所有索引
   $res = $cl->Query ( $q, $index );$cl->Query()返回的内容print_r后大概是:

Array
(
   [error] =>
   [warning] =>
   [status] => 0
   [fields] => Array
   (
      [0] => title
      [1] => contents
      [2] => author
   )
   [attrs] => Array
   (
      [catalogid] => 1
      [addtime] => 2
      [edituserid] => 1
      [hits] => 1
   )
   [matches] => Array
   (
      [380] => Array
             (
               [weight] => 1
               [attrs] => Array
                  (
                         [catalogid] => 7
                         [addtime] => 1112677492
                         [edituserid] => 1
                         [hits] => 1470
                  )              )
      [599] => Array
             (
               [weight] => 101
               [attrs] => Array
                  (
                         [catalogid] => 7
                         [addtime] => 1115910729
                         [edituserid] => 1
                         [hits] => 1749
                  )              )
      [850] => Array
             (
               [weight] => 1
               [attrs] => Array
                  (
                         [catalogid] => 2
                         [addtime] => 1118741392
                         [edituserid] => 1
                         [hits] => 289
                  )              )
      [877] => Array
             (
               [weight] => 1
               [attrs] => Array
                  (
                         [catalogid] => 2
                         [addtime] => 1118898869
                         [edituserid] => 1
                         [hits] => 9870
                  )              )
      [1040] => Array
             (
               [weight] => 101
               [attrs] => Array
                  (
                         [catalogid] => 2
                         [addtime] => 1120708579
                         [edituserid] => 1
                         [hits] => 318
                  )              )
   )
   [total] => 129
   [total_found] => 129
   [time] => 0.000
   [words] => Array
   (
      [design] => Array
             (
               [docs] => 129
               [hits] => 265
             )
   )
)从上面可以看出Query并不能全部取得我们想要的记录内容,比如说Title,Contents字段就没有取出来,根据官方的说明是sphinx并没 有连到mysql去取记录,只是根据它自己的索引内容进行计算,因此如果想用sphinxAPI去取得我们想要的记录,还必须将Query的结果为依据去 查询MySQL才可以得到最终我们想要的结果集。

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

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

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

require ( "sphinxapi.php" );
$docs = array
(
"this is my test text to be highlighted, and for the sake of the testing we need to pump its length somewhat",
"another test text to be highlighted, below limit",
"test number three, without phrase match",
"final test, not only without phrase match, but also above limit and with swapped phrase text test as well",
);
$words = "test";
$index = "cgfinal";
$opts = array
(
"before_match"   => "<span style='font-weight:bold;color:red'>",
"after_match"   => "</span>",
"chunk_separator" => " ... ",
"limit" => 60,
"around" => 3,
);

foreach ( array(0,1) as $exact )
{
$opts["exact_phrase"] = $exact;
print "exact_phrase=$exact\n";

$cl = new SphinxClient ();
$res = $cl->BuildExcerpts ( $docs, $index, $words, $opts );
if ( !$res )
{
   die ( "ERROR: " . $cl->GetLastError() . ".\n" );
} else
{
   $n = 0;
   foreach ( $res as $entry )
   {
$n++;
print "n=$n, res=$entry<br/>";
   }
   print "\n";
}
}在IE上运行的效果是:

在实际环境中,上面代码的$docs是我们用sphinx搜索出来的结果,这个结果利用BuildExcerpts方法可以实现摘要的功能。

采用SphinxSE方式调用Sphinx

采用sphinxSE必须要求为mySQL安装sphinxSE Engine驱动,方法在第1节中我已讲到

要创建一张sphinx 专用表,你可以这样建

CREATE TABLE `sphinx` (
`id` int(11) NOT NULL,
`weight` int(11) NOT NULL,
`query` varchar(255) NOT NULL,
`CATALOGID` INT NOT NULL,
`EDITUSERID` INT NOT NULL,
`HITS` INT NULL,
`ADDTIME` INT NOT NULL,
KEY `Query` (`Query`)
) ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION='sphinx://localhost:3312/cgfinal';警告

注:与一般mysql表不同的是ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION='sphinx://localhost:3312/cgfinal';,这里表示这个表采用SPHINXSE引擎,字符集是 utf8,与sphinx的连接串是'sphinx://localhost:3312/cgfinal,cgfinal是索引名称

根据sphinx官方说明,这个表必须至少有三个字段,字段起什么名称无所谓,但类型的顺序必须是integer,integer,varchar,分别 表示记录标识document ID,匹配权重weight与查询query,同时document ID与query必须建索引。另外这个表还可以建立几个字段,这几个字段的只能是integer或TIMESTAMP类型,字段是与sphinx的结果集 绑定的,因此字段的名称必须与在sphinx.conf中定义的属性名称一致,否则取出来的将是Null值。

比如我在上面有定义了sql_attr_uint= CATALOGID,sql_attr_uint= EDITUSERID,sql_attr_uint = HITS,sql_attr_timestamp = ADDTIME,那么在这个表里头,你就可以再定义CATALOGID,EDITUSERID,HITS,ADDTIME四个字段。

通过sql语句实现查询。通过select * from sphinx where query='sphinx表达式' 的方式可以实现查询,通过让sphinx表与eht_articles或其他表并联查询(条件是sphinx.id= eht_articles.Articlesid)还可以实现更为复杂的sql,基本上可以符合我们日常的要求。

sphinx表达式在sphinx的手册中也提到了,这里我简单说明几条:

query='关键字' ,关键字就是你要搜索的关键字,如query='CGArt'表示你要全文搜索CGArt
mode,搜索模式,值有:all,any,phrase,boolean,extended,默认是all
sort,排序模式,必须是relevance,attr_desc,attr_asc,time_segments,extended中的一种,在所有模式中除了relevance外,
   属性名(或用extended排序)前面都需要一个冒号。
... where query='test;sort=attr_asc:hits';
   ... where query='test;sort=extendedweight desc,hits asc';
offset,结果记录集的起始位置,默认是0
limit,从结果记录集中取出的数量,默认是20条
index,要搜索的索引名称
   ... where query='test;index=cgfinal';
   ... where query='test;index=test1,test2,test3;';
minid,maxid,匹配最小与最大文档ID
weights,以逗号分割的分配给sphinx全文检索字段的权重列表
... where query='test;weights=1,2,3;';
filter,!filter,以逗号分隔的属性名与一堆要匹配的值
#只包括1,5,19的组
... where query='test;filter=group_id,1,5,19;';
   #不包括3,11的组
... where query='test;!filter=group_id,3,11';
range,!range,逗号分隔的属性名一最小与最大要匹配的值
#从3至7的组
... where query='test;range=group_id,3,7;';
#不包括从5至25的组
... where query='test;!range=group_id,5,25;';
maxmatches,每个查询最大匹配的值
... where query='test;maxmatches=2000;';
groupby,group by 方法与属性
... where query='test;groupby=day:published_ts;';
... where query='test;groupby=attr:group_id;';
groupsort,group by 的排序
... where query='test;gropusort='@count desc';需要注意的重要一点是让sphinx进行排序,过滤,切分结果记录集比用MySQL的where,orderby 和limit将有更好的效率。有两个原因,首先sphinx做了很多优化,在这些任务上它比mySQL做得更出色,其次searchd在打包, sphinxSE在传输与解包上需要的数据量更少。

你可以通过运用join在sphinxSE的搜索表和其他引擎类型的表做并联查询。这有一个从example.sql中documents表的例子:

mysql> SELECT content, date_added FROM test.documents docs
-> JOIN t1 ON (docs.id=t1.id)
-> WHERE query="one document;mode=any";
+-------------------------------------+---------------------+
| content                             | docdate          |
+-------------------------------------+---------------------+
| this IS my test document number two | 2006-06-17 14:04:28 |
| this IS my test document number one | 2006-06-17 14:04:28 |
+-------------------------------------+---------------------+
2 rows IN SET (0.00 sec)

mysql> SHOW ENGINE SPHINX STATUS;
+--------+-------+---------------------------------------------+
| Type | Name   | STATUS                                      |
+--------+-------+---------------------------------------------+
| SPHINX | stats | total: 2, total found: 2, time: 0, words: 2 |
| SPHINX | words | one:1:2 document:2:2                      |
+--------+-------+---------------------------------------------+
2 rows IN SET (0.00 sec)8. SphinxSE的SQL查询例子演练

从eht_articles中查询标题含有“动画”关键字的记录。

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画;mode=extended'提示

说明:要指定某个字段进行搜索,要用@字段名+空格+关键字+分号+mode=extended 如果不指定字段,则系统会对TITLE,CONTENTS进行搜索 ,对什么字段进行全文检索取决于在sphinx.conf中sql_query定义的select 中的字段(文本类型)

从eht_articles中查询文章内容或标题含有“CGArt”关键字的记录。

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=sphinx.id AND query='动画'若AUTHOR,TITLE,CONTENTS三个字段都全文索引了,但只想搜title,或contents中含有“动画”关键字 的文章

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画 | @contents 动画;
mode=extended'查询标题含有“动画”关键字,catalogid为7,edituserid为1的记录

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画;
filter=edituserid,1;filter=catalogid,7;mode=extended'提示

采用filter=字段名称,值就相当于where中的 字段名=值,filter提到的字段必须在sphinx的source部分的字段属性定义中定义,如

sql_attr_uint = CATALOGID
sql_attr_uint = EDITUSERID
sql_attr_uint = HITS
sql_attr_timestamp = ADDTIME查询标题含有“动画”关键字,按人气Hits从大至小,栏目ID从大至小排序

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画;mode=extended;
sort=extended:hits desc,catalogid desc'在sphinx中,select出来的内容是按weight从大至小排序的,weight是根据sphinx内部一定的算法算出来的,越大就表 示越匹配,如果想按匹配度从大至小排序,则可以:

SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画;mode=extended;
sort=@weight desc'搜内容或标题含有优秀或Icon或设计,按catalogid分组,按匹配度从高至低排序

SELECT t.*,c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='优秀 | Icon | 设计;
mode=extended;groupby=attr:catalogid;groupsort=@weight;'9. 如何自动重建索引

如何调用Sphinx 和api接口相关推荐

  1. python有道api-python 调用有道api接口的方法

    初学python ,研究了几天,写了一个python 调用 有道api接口程序 效果看下图: 申明:代码仅供和我一样的初学者学习交流 申请很简单的 ps:审核不用花时间的,请勿滥用!! #-*- co ...

  2. python实现简单的api接口-简单实现Python调用有道API接口(最新的)

    # ''' # Created on 2018-5-26 # # @author: yaoshuangqi # ''' import urllib.request import urllib.pars ...

  3. 用Python调用华为云API接口发短信

    [摘要] 用Python调用华为云API接口实现发短信,当然能给调用发短信接口前提条件是通过企业实名认证,而且有一个通过审核的短信签名,话不多说,showcode #!/usr/bin/python3 ...

  4. python api接口调用_python 调用有道api接口的方法

    初学者学习python,研究了几天之后,我写了一个python程序调用有道api接口.效果如下图所示:声明:代码仅仅是像我这样的初学者学习和交流.应用程序非常简单.PS:评审不需要时间,请不要滥用!! ...

  5. java调用第三方天气预报API接口

    java调用第三方天气预报API接口 package com.sensordata.controller; import com.common.json.JSONObject; import java ...

  6. 如何调用股票交易软件api接口?

    随着人们的生活水平越来越高,人们可以通过公司的股票交易软件api接口来查询股票,也可以用股票交易软件api接口来了解股市,采用正规的界面可以确保数据的准确性,及时的根据股价的涨跌幅度做出一些选择,所以 ...

  7. 【2019-07-23】]python3 把日语翻译为中文 调用百度翻译API接口及API申请使用教程

    点击申请百度翻译API,得到一个你自己的API账户. 点击查看申请教程,感谢教程原作者. API官网提供了一个python2的使用接口的demo还有详细的解释文档 想用python3完成,代码几乎照搬 ...

  8. java版微信朋友圈_java调用个人微信API接口发朋友圈,评论和删除朋友圈

    java调用个人微信API接口发朋友圈,评论和删除朋友圈 /** * 发送朋友圈任务 * @author wechatno:tangjinjinwx * @param ctx * @param vo ...

  9. java调用个人微信api接口实现收发消息发朋友圈

    个人微信api接口,java调用个人微信api接口实现收发消息发朋友圈 1.微信好友收发消息         /**      * 给微信好友发消息      * @author wechatno:t ...

  10. 快递接口API:用JS调用快递鸟API接口进行快递单号查询

    本文实例为大家分享了JS调用快递鸟API接口,来实现600多家的物流轨迹查询,完成快递单号查询的具体代码,供大家参考,具体内容如下 只需要一步,新建一个Text文本,把下面这段代码复制进去,替换你自己 ...

最新文章

  1. ASP.NET中树形图的实现
  2. T-SQL操作XML 数据类型方法 modify 的参数 1 必须是字符串文字。
  3. mysql gtid 1236_MYSQL主从搭建GTID报错 error 1236 master has purged binary logs containing GTIDs?...
  4. Django 的视图层
  5. python学习笔记(二)---编辑工具sublimeText3运行python
  6. Linux 与 硬件 —— 各个硬件设备在Linux中的文件名
  7. css中属性兼容性写法,CSS3兼容属性和标准属性的书写顺序
  8. 完整的可按年份和月份查询数据并显示
  9. 汉化:Termius for Mac(SSH客户端)
  10. 论文笔记_S2D.43_2018-CVPR_单张RGB-D图像的深度补全
  11. python实现一个json文件任意路径形式的接口项目
  12. html5设计基础报告,《网页设计与制作基础》实验报告.doc
  13. 超级安全!Python 合成多张图片到PDF格式
  14. shl归纳推理测试题库_SHL测评:KPMG经典24题,KPMG经典36题
  15. Ds918 ds3615 ds3617区别_红、白葡萄酒间真正的区别
  16. 2017博鳌亚洲青年论坛(香港)顺利召开 中国发展人工智能优势在哪?
  17. IoT中的高音质音频设计
  18. 少年,我看你骨骼精奇,见与你有缘,这套算法赠你
  19. Android 一款十分简洁、优雅的日记APP
  20. 自然之美--记冬夏黄山

热门文章

  1. 在线latex的一些操作
  2. Slider网站欣赏
  3. day_05 运算符 if和while的使用
  4. quast 的结果怎么看_使用quast评估基因组装配的质量
  5. Python常见低级错误/拼写错误
  6. vue3关闭语法错误提示
  7. C语言复健(数组) 珠心算测验
  8. 国内跨省游正式开放!旅行社要怎么抓住这个机会?
  9. 华硕X370 Pro更新BIOS后黑屏自救记录
  10. 分享《模拟专升本考试排名》