sphinx使⽤教程-挺简单易懂
使⽤打开控制台,必需打开控制台PHP才能连接到sphinx(确保你已经建⽴好索引源):
d:\coreseek\bin\searchd -c d:\coreseek\f
coreseek/api⽬录下提供了PHP的接⼝⽂件 sphinxapi.php,这个⽂件包含⼀个SphinxClient的类
在PHP引⼊这个⽂件,new⼀下
01$sphinx = new SphinxClient();
02
03//sphinx的主机名和端⼝
04
05$sphinx->SetServer ( 'loclahost', 9312 );
06
07//设置返回结果集为php数组格式
08
09$sphinx->SetArrayResult ( true );
10
11//匹配结果的偏移量,参数的意义依次为:起始位置,返回结果条数,最⼤匹配条数
12
13$sphinx->SetLimits(0, 20, 1000);
14
15//最⼤搜索时间
16
17$sphinx->SetMaxQueryTime(10);
18
19
20
21//执⾏简单的搜索,这个搜索将会查询所有字段的信息,要查询指定的字段请继续看下⽂
22
23$index = 'email' //索引源是配置⽂件中的 index 类,如果有多个索引源可使⽤,号隔开:'email,diary' 或者使⽤'*'号代表全部索引源
24
25$result = $sphinx->query ('搜索关键字', $index);
26
27echo '<pre>';
28
29print_r($result);
30
31echo '</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 ema
il
所以matches中的ID是指emailid
⾄于weight是指匹配的权重,⼀般权重越⾼被返回的优先度也最⾼,匹配权重相关内容请参考官⽅⽂档
attrs是配置⽂件中sql_attr_ 中的信息,稍后会提到这些属性的⽤法
说了这么多,即使搜索到结果也不是我们想要的email数据,但事实sphinx是不记录真实数据的,所以要获取到真实email数据还要根据matches中的ID去搜索mysql的email表,但总体来说这样⼀来⼀回的速度还是远远⽐mysql的LIKE快得多,前提是⼏⼗万数据量以上,否则⽤sphinx只会更慢。
接下来介绍sphinx⼀些类似mysql条件的⽤法
01//emailid的范围
02
03$sphinx->SetIdRange($min, $max);
04
05
06
07//属性过滤,可过滤的属性必需在配置⽂件中设置sql_attr_ ,之前我们定义了这些
08
09 sql_attr_uint = fromid
10
11 sql_attr_uint = toid
12
13 sql_attr_timestamp = sendtime
14
15//如果你想再次修改这些属性,配置完成后记得重新建⽴索引才能⽣效
16
17
18
19//指定⼀些值
20
21$sphinx->SetFilter('fromid', array(1,2)); //fromid的值只能是1或者2
22
23//和以上条件相反,可增加第三个参数
24
25$sphinx->SetFilter('fromid', array(1,2), false); //fromid的值不能是1或者2
26
27//指定⼀个值的范围
28
29$sphinx->SetFilterRange('toid', 5, 200); //toid的值在5-200之间
30
31//和以上条件相反,可增加第三个参数
32
33$sphinx->SetFilterRange('toid', 5, 200, false); //toid的值在5-200以外
34
35
36
37//执⾏搜索
38
39$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 模式,按某个算术表达式排序
mysql操作官方文档
01//使⽤属性排序
02
03//以fromid倒序排序,注意当再次使⽤SetSortMode会覆盖上⼀个排序
04
05$sphinx->SetSortMode ( "SPH_SORT_ATTR_DESC", 'fromid');
06
07//如果要使⽤多个字段排序可使⽤SPH_SORT_EXTENDED模式
08
09//@id是sphinx内置关键字,这⾥指emailid,⾄于为什么是emailid,⾃⼰思考⼀下
10
11$sphinx->SetSortMode ( "SPH_SORT_ATTR_DESC", 'fromid ASC, toid DESC, @id DESC');
12
13//执⾏搜索
14
15$result = $sphinx->query('关键字', '*');
16
17//更多请查看官⽅⽂档排序模式的说明
匹配模式
有如下可选的匹配模式:
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的条件语句
01//设置扩展匹配模式
02
03$sphinx->SetMatchMode ( "SPH_MATCH_EXTENDED2" );
04
05//查询中使⽤条件语句,字段⽤@开头,搜索内容包含测试,toid等于1的邮件:
06
07$result = $sphinx->query('@content (测试) & @toid =1', '*');
08
09//⽤括号和&(与)、|、(或者)、-(⾮,即!=)设置更复杂的条件
10
11$result = $sphinx->query('(@content (测试) & @subject =呃) | (@fromid -(100))', '*');
12
13//更多语法请查看官⽅⽂档匹配模式的说明
扩展匹配模式中值得⼀提的是搜索的字段,如果该字段被设置属性,那么扩展匹配搜索的字段默认是不包含这些属性的,只能⽤SetFilter()或者SetFilterRange()之类
之前我们设置了fromid、toid、sendtime为属性,但⼜想在扩展匹配模式中⼜想⽤作条件该怎么办?
只要在sql_query语句中再选择多⼀次该字段就可以了
sql_query = SELECT emailid,fromid,fromid,toid,toid,subject,content,sendtime,sendtime,attachement FROM email
//设置完成记得重新建⽴索引
更多条件技巧
只是⼀些技巧,但不建议使⽤的部署环境中,⾄于为什么,请看⽂章结尾
<、<=、>、>=
默认sphinx没有这些⽐较符。
假如我想邮件的发送时间⼤于某⼀⽇期怎么办?⽤SetFilterRange()⽅法模拟⼀下
01//⼤于等于某⼀时间截$time
02
03$sphinx->SetFilterRange('sendtime', $time, 10000000000) //时间截最⼤是10个9,再加1是不可超越了。。
04
05
06
07//⼤于某⼀时间截$time
08
09$sphinx->SetFilterRange('sendtime', $time+1, 10000000000)
10
11//⼩于等于某⼀时间截$time
12
13$sphinx->SetFilterRange('sendtime', -1, $time) //时间截最⼩是0,所以应该减1
14
15//⼤于某⼀时间截$time
16
17$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()
1//搜索包含附件ID为1或2邮件,mysql语法是这样FIND_IN_SET(`attachment`, '1,2')
2
3$sphinx->SetFilter('attachment', array(1,2))
4
5//可以使⽤SetFilterRange,搜索包含附件ID在50-100范围的邮件
6
7$sphinx->SetFilterRange('attachment', 50, 100)
总结
如果你想⼀个免费、好⽤、极速的全⽂搜索引擎,sphinx⽆疑是最好的选择,但是不要忘记sphinx的⽬的:全⽂检索。不要去想那些乱七⼋糟条件。你想要把sphinx搜索变得像mysql那样灵活,可完全单独⽤在⼀些复杂的多条件搜索,像某些邮件的⾼级搜索,那么我建议你还是多花点时间在PHP或者mysql代码的优化上,因为那样可能会让你的搜索变得更慢。
最好的⽅法是以最简单的⽅法搜索到内容,将ID交还mysql数据库搜索。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论