Sphinx如何实现搜索结果过滤功能

一般网站的搜索功能,用Sphinx做个没什么过滤条件的全文检索功能,基本上能满足网站的部分功能。然而,在很大部分情况下,是需要做检索的结果过滤(需求描述:假如我们要搜索学生档案。a.只需要查找性别为“男”的学生;  b:只要搜索学生年龄在:18至20岁之前的学生档案)。这个时候,我们就需要用到Sphinx的结果集过滤设置功能了。

通过Sphinx PHP API 文档(Sphinx 0.9.8),得到结果集过滤接口有以下几个方法:
  • 5.4.1. SetIDRange
  • 5.4.2. SetFilter
  • 5.4.3. SetFilterRange
  • 5.4.4. SetFilterFloatRange
  • 5.4.5. SetGeoAnchor
篇幅原因这里我不对接口一一做介绍,我只抽取其中两个方法做说明,正好解决上面提到的二个需求:
第一:SetFilter  (解决需求a:只需要查找性别为“男”的学生)
注意:必须是无符号整数属性(sql_attr_uint )
原型: function SetFilter ( $attribute, $values, $exclude=false )
增加整数值过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名。$values是整数数组。
$exclude是布尔值,它控制是接受匹配的文档(默认模式,即$exclude为假时)还是拒绝它
们。
只有当索引中$attribute列的值与$values中的任一值匹配时文档才会被匹配(或者拒绝,如
果$exclude值为真)
第二:SetFilterRange  (解决需求b:只要搜索学生年龄在:18至20岁之前的学生档案)
注:可以是浮点型属性(sql_attr_float ) 和 无符号整数属性(sql_attr_uint )
原型 : function SetFilterRange ( $attribute, $min, $max, $exclude=false )
添加新的整数范围过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名, $min、$max定义了
一个整数闭区间,$exclude布尔值,它控制是接受匹配的文档(默认模式,即$exclude为
假时)还是拒绝它们。
只有索引中$attribute列的值落在$min和$max之间(包括$min和$max),文档才会被匹配
(或者拒绝,如果$exclude值为真)。
在搜索的程序要用这几个接口,不是我们想像的那样,直接在程序里直接调用就能用的,如果你在Sphinx数据源配置文件里没有配置置对应的属性,用这个过滤是不生效的(搜索失败,直接报错)。
在使用过滤功能时,需要注意以下两点就行:
1.在sphinx.conf(名称换成您的数据源配置文件)文件里修改如下配置,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 # [注:性别,这里要用SetFilter,就必须用sql_attr_uint这属于性。来源:www.oophp.cn]
 sql_attr_uint = gender

 # [注:年龄,SetFilterRange可以用,sql_attr_uint也可以用。来源:www.oophp.cn]
 sql_attr_float = age
}
2.在sphinx.conf的数据源SQL中,把需要过滤的字段相应增加到数据源中,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 sql_query =  SELECT id, gender, age, username,
              introduction FROM student  ORDER  BY id  DESC
}
按上面的方式修改数据源配置,重新生成一次全量索引后。直接var_dump检测看是否属性设置是否生效,类似输出这个:
array(9) {
 ["error"]=>
 string(0) ""
 ["warning"]=>
 string(0) ""
 ["status"]=>
 int(0)
 ["fields"]=>
 array(2) {
 [0]=>
 string(5) "username"
 [1]=>
 string(12) "introduction"
 }
 ["attrs"]=>
 array(6) {
 ["id"]=>
 int(1)
 ["gender"]=>
 int(2)
 ["age"]=>
 ["@expr"]=>
 int(5)
 }
 ["matches"]=>
 array(10) {
 [266652]=>
 }
 .......
 }
如果能看到属性区有genderage,就证明修改的配置已生效。这个时候在程序里通过调用相应的接口就能得到正确数据的结果。类似如下:
<?php
$sphinx = new SphinxClient();
$sphinx->SetServer('127.0.0.1','9312');
$sphinx->SetConnectTimeout(1);
$sphinx->SetLimits(0,10);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
$sphinx->SetSortMode (SPH_SORT_EXPR,
            "@weight*50000+age+ln(id)*100000" );
//做相应的过滤处理
 //1代表男生
$sphinx->SetFilter('gender',array(1));
//取到18到20岁的学生档案
$sphinx->SetFilterFloatRange('age',18,20);

.......
参考资料:
http://blog.csdn.net/adparking/article/details/6445926
http://www.coreseek.cn/
http://www.wapm.cn/uploads/pdf/sphinx_doc_zhcn_0.9.pdf

发表评论

电子邮件地址不会被公开。 必填项已用*标注