Sphinxmysql 关联查询 排序排序是怎样工作的

> 博客详情
可使用如下模式对搜索结果排序:
SPH_SORT_RELEVANCE 模式, 按相关度降序排列(最好的匹配排在最前面)
SPH_SORT_ATTR_DESC 模式, 按属性降序排列 (属性值越大的越是排在前面)
SPH_SORT_ATTR_ASC 模式, 按属性升序排列(属性值越小的越是排在前面)
SPH_SORT_TIME_SEGMENTS 模式, 先按时间段(最近一小时/天/周/月)降序,再按相关度降序
SPH_SORT_EXTENDED 模式, 按一种类似SQL的方式将列组合起来,升序或降序排列。
SPH_SORT_EXPR 模式,按某个算术表达式排序。
SPH_SORT_EXTENDED 模式
在 SPH_SORT_EXTENDED 模式中,您可以指定一个类似SQL的排序表达式,但涉及的属性(包括内部属性)不能超过5个,例如:
@relevance DESC, price ASC, @id DESC
只要做了相关设置,不管是内部属性(引擎动态计算出来的那些属性)还是用户定义的属性就都可以使用。内部属性的名字必须用特殊符号@开头,用户属性按原样使用就行了。在上面的例子里,@relevance和@id是内部属性,而price是用户定义属性。
已知的内置属性:
@id (匹配文档的 ID)
@weight (匹配权值)
@rank (等同 weight)
@relevance (等同 weight)
(随机顺序返回结果)
@rank&和&@relevance&只是&@weight&的别名.
PHP 的 API 中只有 SetSortMode($mode, $sortBy) 方法.从上面的文档说明中可知,如果需要设置多个字段依次排序。需要使用下列代码:
$SphinxClient-&SetSortMode(SPH_SORT_EXTENDED, "columnA ASC, columnB DESC, columnC ASC");
无法方便的同时设置多个排序。通过继承 SphinxClient 类添加了一个新方法,实现了通过数组设置多个排序。
* 设定多重排序条件
* @param Array $orders 排序条件数组
* @example $order = array (
'0' =& array ('attribute' =& 'columnname', 'order' =& RentSearch::DESC),
'1' =& array (//...),
public function multiOrder($orders) {
$orderType = SPH_SORT_EXTENDED;
$orderString = "";
foreach ($orders as $order) {
switch ($order['order']) {
case self::ASC :
$orderString += $order['attribute'] . ' ASC, ';
case self::DESC :
$orderString += $order['attribute'] . ' DESC, ';
$orderString += $order['attribute'] . ' DESC, ';
$orderString = substr($orderString, 0, strlen($orderString)-2);
$this-&SetSortModel($orderType, $orderString);
人打赏支持
码字总数 1897
相关配置就是你想设置的排序,$SphinxClient-&SetSortMode(SPH_SORT_EXTENDED, &columnA ASC, @id DESC&); 这样就是同事使用内部和外部属性排序。
我估计是跟词表有关,DD并不是一个词,所以建的索引里面不会有 DD 的。搜索的时候被分词成了 D。
请问你是怎么解决的呢
,感激不尽呢!!!
引用来自“Deacyn”的评论请问你是怎么解决的呢
,感激不尽呢!!!使用自己的词表,查一下手册就知道了。
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥1131人阅读
PHP 语言(112)
如何调用Sphinx按上面配置,第5节点对数据库进行了索引,通过Sphinx自带的search(在bin/release目录)就可以在命令行进行搜索:来源:/ndlli/blog/item/cefb43a9ad93.html(搜索CGArt)windows上:search -c d:/sphinx/sphinx.conf CGArtLinux上: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] =& &&&&&&&&&&&&&&&&&&&&&&&& [edituserid] =& 1&&&&&&&&&&&&&&&&&&&&&&&& [hits] =& 1470&&&&&&&&&&&&&&&&& )&&&&&&&&&&&&& )&&&&& [599] =& Array&&&&&&&&&&&& (&&&&&&&&&&&&&& [weight] =& 101&&&&&&&&&&&&&& [attrs] =& Array&&&&&&&&&&&&&&&&& (&&&&&&&&&&&&&&&&&&&&&&&& [catalogid] =& 7&&&&&&&&&&&&&&&&&&&&&&&& [addtime] =& &&&&&&&&&&&&&&&&&&&&&&&& [edituserid] =& 1&&&&&&&&&&&&&&&&&&&&&&&& [hits] =& 1749&&&&&&&&&&&&&&&&& )&&&&&&&&&&&&& )&&&&& [850] =& Array&&&&&&&&&&&& (&&&&&&&&&&&&&& [weight] =& 1&&&&&&&&&&&&&& [attrs] =& Array&&&&&&&&&&&&&&&&& (&&&&&&&&&&&&&&&&&&&&&&&& [catalogid] =& 2&&&&&&&&&&&&&&&&&&&&&&&& [addtime] =& &&&&&&&&&&&&&&&&&&&&&&&& [edituserid] =& 1&&&&&&&&&&&&&&&&&&&&&&&& [hits] =& 289&&&&&&&&&&&&&&&&& )&&&&&&&&&&&&& )&&&&& [877] =& Array&&&&&&&&&&&& (&&&&&&&&&&&&&& [weight] =& 1&&&&&&&&&&&&&& [attrs] =& Array&&&&&&&&&&&&&&&&& (&&&&&&&&&&&&&&&&&&&&&&&& [catalogid] =& 2&&&&&&&&&&&&&&&&&&&&&&&& [addtime] =& &&&&&&&&&&&&&&&&&&&&&&&& [edituserid] =& 1&&&&&&&&&&&&&&&&&&&&&&&& [hits] =& 9870&&&&&&&&&&&&&&&&& )&&&&&&&&&&&&& )&&&&& [1040] =& Array&&&&&&&&&&&& (&&&&&&&&&&&&&& [weight] =& 101&&&&&&&&&&&&&& [attrs] =& Array&&&&&&&&&&&&&&&&& (&&&&&&&&&&&&&&&&&&&&&&&& [catalogid] =& 2&&&&&&&&&&&&&&&&&&&&&&&& [addtime] =& &&&&&&&&&&&&&&&&&&&&&&&& [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:color:red'&&,&after_match&&& =& &&/span&&,&chunk_separator& =& & ... &,&limit& =& 60,&around& =& 3,);foreach ( array(0,1) as $exact ){$opts[&exact_phrase&] = $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'表示你要全文搜索CGArtmode,搜索模式,值有:all,any,phrase,boolean,extended,默认是allsort,排序模式,必须是relevance,attr_desc,attr_asc,time_segments,extended中的一种,在所有模式中除了relevance外,&& 属性名(或用extended排序)前面都需要一个冒号。... where query='sort=attr_asc:hits';&& ... where query='sort=extendedweight desc,hits asc';offset,结果记录集的起始位置,默认是0limit,从结果记录集中取出的数量,默认是20条index,要搜索的索引名称&& ... where query='index=cgfinal';&& ... where query='index=test1,test2,test3;';minid,maxid,匹配最小与最大文档IDweights,以逗号分割的分配给sphinx全文检索字段的权重列表... where query='weights=1,2,3;';filter,!filter,以逗号分隔的属性名与一堆要匹配的值#只包括1,5,19的组... where query='filter=group_id,1,5,19;';&& #不包括3,11的组... where query='!filter=group_id,3,11';range,!range,逗号分隔的属性名一最小与最大要匹配的值#从3至7的组... where query='range=group_id,3,7;';#不包括从5至25的组... where query='!range=group_id,5,25;';maxmatches,每个查询最大匹配的值... where query='maxmatches=2000;';groupby,group by 方法与属性... where query='groupby=day:published_';... where query='groupby=attr:group_';groupsort,group by 的排序... where query='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=&mode=any&;+-------------------------------------+---------------------+| content&&&&&&&&&&&&&&&&&&&&&&&&&&&& | docdate&&&&&&&&& |+-------------------------------------+---------------------+| this IS my test document number two |
14:04:28 || this IS my test document number one |
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 = CATALOGIDsql_attr_uint = EDITUSERIDsql_attr_uint = HITSsql_attr_timestamp = ADDTIME查询标题含有“动画”关键字,按人气Hits从大至小,栏目ID从大至小排序SELECT c.* FROM eht_articles AS c,sphinx AS t WHERE c.articlesid=t.id AND query='@title 动画;mode=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=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=groupby=attr:groupsort=@'9. 如何自动重建索引
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:467826次
积分:6981
积分:6981
排名:第2989名
原创:244篇
转载:79篇
评论:32条
(1)(3)(4)(3)(8)(9)(4)(2)(4)(5)(5)(5)(1)(3)(7)(12)(1)(7)(1)(6)(6)(5)(3)(1)(1)(2)(4)(3)(6)(9)(17)(2)(3)(3)(3)(1)(8)(1)(5)(2)(4)(1)(5)(12)(4)(6)(12)(7)(8)(23)(9)(7)(6)(9)(8)(46)问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
我用sphinx做一个距离排序的功能,现在报了一个错误,index distance: unknown latitude attribute 'latitude'
$log = 110.362616;
$lat = 20.030727;
$radius = (float) 10000.0 * 1.61; //搜索10公里以内的地点
$sphinx = new Sphinx();
$sphinx-&SetMatchMode(SPH_MATCH_ANY);
$sphinx-&SetSortMode(SPH_SORT_EXPR, "@weight");
$sphinx-&SetGeoAnchor('latitude', 'longitude',$lat * M_PI/180.0,$log * M_PI/180.0);
$sphinx-&SetSortMode(SPH_SORT_EXTENDED, '@geodist ASC'); // 按距离正向排序
$sphinx-&SetFilterFloatRange('@geodist', 0.0, $radius); // 过滤掉大于10公里的地点
$result = $sphinx-&Query('', '*');
我在sphinx配置的sql是sql_query
= select RADIANS(longitude) as longitude,RADIANS(latitude) as atitude from distance
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
需要在配置文件写下sql_query
= select *,RADIANS(latitude) AS latitude,RADIANS(longitude) AS longitude from distance
sql_attr_float = latitudesql_attr_float = longitude
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
扫扫下载 App问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
SetMatchMode( SPH_MATCH_EXTENDED2 );
SetRankingMode ( SPH_RANK_PROXIMITY_BM25 );
setFieldWeights( array('title' =& 10, 'body' =& 1) );
Query( "固废|技术|污水|趋势", "*" );
怎么能让“固废|技术”的优先级高于“污水|趋势”,
保证最大匹配“固废和技术”
同步到新浪微博
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
扫扫下载 App2292人阅读
使用打开控制台,必需打开控制台PHP才能连接到sphinx(确保你已经建立好索引源):
d:\coreseek\bin\searchd&-c&d:\coreseek\bin\sphinx.conf
coreseek/api目录下提供了PHP的接口文件&sphinxapi.php,这个文件包含一个SphinxClient的类
在PHP引入这个文件,new一下
$sphinx&=&new&SphinxClient();
//sphinx的主机名和端口
$sphinx-&SetServer (&'loclahost', 9312 );
//设置返回结果集为php数组格式
$sphinx-&SetArrayResult ( true );
//匹配结果的偏移量,参数的意义依次为:起始位置,返回结果条数,最大匹配条数
$sphinx-&SetLimits(0, 20, 1000);
//最大搜索时间
$sphinx-&SetMaxQueryTime(10);
//执行简单的搜索,这个搜索将会查询所有字段的信息,要查询指定的字段请继续看下文
$index&=&'email'&//索引源是配置文件中的 index 类,如果有多个索引源可使用,号隔开:'email,diary' 或者使用'*'号代表全部索引源
$result&=&$sphinx-&query ('搜索关键字',&$index);
echo&'&pre&';
print_r($result);
echo&'&/pre&';
$result是一个数组,其中
total是匹配到的数据总数量
matches是匹配的数据,包含id,attrs这些信息
words是搜索关键字的分词
你可能奇怪为什么没有邮件的内容这些信息,其实sphinx并不会返回像mysql那样的数据数组,因为sphinx本来就没有记录完整的数据,只记录被分词后的数据。
具体还要看matches数组,matches中的ID就是指配置文件中sql_query&SELECT语句中的第一个字段,我们配置文件中是这样的
sql_query&&&&&&&&&&&&&&&&=&SELECT&emailid,fromid,toid,subject,content,sendtime,attachement&FROM&email
所以matches中的ID是指emailid
至于weight是指匹配的权重,一般权重越高被返回的优先度也最高,匹配权重相关内容请参考官方文档
attrs是配置文件中sql_attr_&&&&中的信息,稍后会提到这些属性的用法
说了这么多,即使搜索到结果也不是我们想要的email数据,但事实sphinx是不记录真实数据的,所以要获取到真实email数据还要根据matches中的ID去搜索mysql的email表,但总体来说这样一来一回的速度还是远远比mysql的LIKE快得多,前提是几十万数据量以上,否则用sphinx只会更慢。
接下来介绍sphinx一些类似mysql条件的用法
//emailid的范围
$sphinx-&SetIdRange($min,&$max);
//属性过滤,可过滤的属性必需在配置文件中设置sql_attr_&&& ,之前我们定义了这些
&&&&sql_attr_uint&&&&&&&&&&& = fromid
&&&&sql_attr_uint&&&&&&&&&&& = toid
&&&&sql_attr_timestamp& = sendtime
//如果你想再次修改这些属性,配置完成后记得重新建立索引才能生效
//指定一些值
$sphinx-&SetFilter('fromid',&array(1,2));&&&&//fromid的值只能是1或者2
//和以上条件相反,可增加第三个参数
$sphinx-&SetFilter('fromid',&array(1,2), false);&&&&//fromid的值不能是1或者2
//指定一个值的范围
$sphinx-&SetFilterRange('toid', 5, 200);&&&&//toid的值在5-200之间
//和以上条件相反,可增加第三个参数
$sphinx-&SetFilterRange('toid', 5, 200, false);&&&&//toid的值在5-200以外
//执行搜索
$result&=&$sphinx-&query('关键字',&'*');
可使用如下模式对搜索结果排序:
SPH_SORT_RELEVANCE&模式,&按相关度降序排列(最好的匹配排在最前面)
SPH_SORT_ATTR_DESC&模式,&按属性降序排列&(属性值越大的越是排在前面)
SPH_SORT_ATTR_ASC&模式,&按属性升序排列(属性值越小的越是排在前面)
SPH_SORT_TIME_SEGMENTS&模式,&先按时间段(最近一小时/天/周/月)降序,再按相关度降序
SPH_SORT_EXTENDED&模式,&按一种类似SQL的方式将列组合起来,升序或降序排列。
SPH_SORT_EXPR&模式,按某个算术表达式排序
//使用属性排序
//以fromid倒序排序,注意当再次使用SetSortMode会覆盖上一个排序
$sphinx-&SetSortMode (&&SPH_SORT_ATTR_DESC&,&'fromid');
//如果要使用多个字段排序可使用SPH_SORT_EXTENDED模式
//@id是sphinx内置关键字,这里指emailid,至于为什么是emailid,自己思考一下
$sphinx-&SetSortMode (&&SPH_SORT_ATTR_DESC&,&'fromid ASC, toid DESC, @id DESC');
//执行搜索
$result&=&$sphinx-&query('关键字',&'*');
//更多请查看官方文档排序模式的说明
有如下可选的匹配模式:
SPH_MATCH_ALL,&匹配所有查询词(默认模式);
SPH_MATCH_ANY,&匹配查询词中的任意一个;
SPH_MATCH_PHRASE,&将整个查询看作一个词组,要求按顺序完整匹配;
SPH_MATCH_BOOLEAN,&将查询看作一个布尔表达式&
SPH_MATCH_EXTENDED,&将查询看作一个CoreSeek/Sphinx内部查询语言的表达式&.&从版本Coreseek&3/Sphinx&0.9.9开始,&这个选项被选项SPH_MATCH_EXTENDED2代替,它提供了更多功能和更佳的性能。保留这个选项是为了与遗留的旧代码兼容——这样即使Sphinx及其组件包括API升级的时候,旧的应用程序代码还能够继续工作。
SPH_MATCH_EXTENDED2,&使用第二版的“扩展匹配模式”对查询进行匹配.
SPH_MATCH_FULLSCAN,&强制使用下文所述的“完整扫描”模式来对查询进行匹配。注意,在此模式下,所有的查询词都被忽略,尽管过滤器、过滤器范围以及分组仍然起作用,但任何文本匹配都不会发生.
我们要关注的主要是SPH_MATCH_EXTENDED2扩展匹配模式,扩展匹配模式允许使用一些像mysql的条件语句
//设置扩展匹配模式
$sphinx-&SetMatchMode (&&SPH_MATCH_EXTENDED2&&);
//查询中使用条件语句,字段用@开头,搜索内容包含测试,toid等于1的邮件:
$result&=&$sphinx-&query('@content (测试) & @toid =1',&'*');
//用括号和&(与)、|、(或者)、-(非,即!=)设置更复杂的条件
$result&=&$sphinx-&query('(@content (测试) & @subject =呃) | (@fromid -(100))',&'*');
//更多语法请查看官方文档匹配模式的说明
扩展匹配模式中值得一提的是搜索的字段,如果该字段被设置属性,那么扩展匹配搜索的字段默认是不包含这些属性的,只能用SetFilter()或者SetFilterRange()之类
之前我们设置了fromid、toid、sendtime为属性,但又想在扩展匹配模式中又想用作条件该怎么办?
只要在sql_query语句中再选择多一次该字段就可以了
sql_query&&&&&&&&&&&&&&&&=&SELECT&emailid,fromid,fromid,toid,toid,subject,content,sendtime,sendtime,attachement&FROM&email
//设置完成记得重新建立索引
更多条件技巧
只是一些技巧,但不建议使用的部署环境中,至于为什么,请看文章结尾
&、&=、&、&=
默认sphinx没有这些比较符。
假如我想邮件的发送时间大于某一日期怎么办?用SetFilterRange()方法模拟一下
//大于等于某一时间截$time
$sphinx-&SetFilterRange('sendtime',&$time, )&//时间截最大是10个9,再加1是不可超越了。。
//大于某一时间截$time
$sphinx-&SetFilterRange('sendtime',&$time+1, )
//小于等于某一时间截$time
$sphinx-&SetFilterRange('sendtime', -1,&$time)&&&&//时间截最小是0,所以应该减1
//大于某一时间截$time
$sphinx-&SetFilterRange('sendtime', -1,&$time&- 1)
IS&NOT&NULL
怎样搜索为空的字段,比如我要搜索附件为空的邮件,有人可能会想&@attachment&('')不就可以了吗?其实这是搜索两个单引号。。。sphinx搜索的字符串不用加引号的
目前sphinx是没有提供这样的功能,其实可以在mysql语句上作手脚:
sql_query&&&&&&&&&&&&&&&&=&SELECT&emailid,fromid,toidsubject,content,sendtime,attachement&!=&''&as&attach is not null&FROM&email&//这里返回了一个新字段attachisnotnull,当attachisnotnull为1的时候附件就不为空了
//设置完成记得重新建立索引
FIND_IN_SET()
搜索包含某一附件的邮件,mysql习惯用FIND_IN_SET这么简单一句就搞定了,在sphinx中必需在配置里设置属性sql_attr_multi&多值属性(MVA):
sql_attr_multi&&&&=&attachment&&&&#attachment可以是逗号分隔的附件ID,或者是空格、分号等sphinx都能识别
//设置完成记得重新建立索引
然后PHP中可以使用SetFilter()
//搜索包含附件ID为1或2邮件,mysql语法是这样FIND_IN_SET(`attachment`, '1,2')
$sphinx-&SetFilter('attachment',&array(1,2))
//可以使用SetFilterRange,搜索包含附件ID在50-100范围的邮件
$sphinx-&SetFilterRange('attachment', 50, 100)
如果你想一个免费、好用、极速的全文搜索引擎,sphinx无疑是最好的选择,但是不要忘记sphinx的目的:全文检索。不要去想那些乱七八糟条件。你想要把sphinx搜索变得像mysql那样灵活,可完全单独用在一些复杂的多条件搜索,像某些邮件的高级搜索,那么我建议你还是多花点时间在PHP或者mysql代码的优化上,因为那样可能会让你的搜索变得更慢。
最好的方法是以最简单的方法搜索到内容,将ID交还mysql数据库搜索。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:23182次
排名:千里之外
原创:18篇
转载:17篇
(1)(1)(1)(1)(6)(11)(6)(1)(4)(1)(4)}

我要回帖

更多关于 excel关联排序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信