6.6.搜索数据
6.6.1.Query (查询)
原型:function Query ( $query, $index="*", $comment="" )
连接到searchd
服务器,根据服务器的当前设置执行给定的查询,取得并返回结果集。
$query
是查询字串,$index
是包含一个或多个索引名的字符串。一旦发生一般错误,则返回假并设置GetLastError()
信息。若成功则返回搜索的结果集。 此外,$comment
将被发送到查询日志中搜索部分的前面,这对于调试是非常有用的。目前,注释的长度限制为128个字符以内。
$index
的默认值是"*"
,意思是对全部本地索引做查询。索引名中允许的字符包括拉丁字母(a-z),数字(0-9),减号(-)和下划线(_),其他字符均视为分隔符。因此,下面的示例调用都是有效的,而且会搜索相同的两个索引:
$cl->Query ( "test query", "main delta" ); $cl->Query ( "test query", "main;delta" ); $cl->Query ( "test query", "main, delta" );
给出多个索引时的顺序是有意义的。如果同一个文档ID的文档在多个索引中找到,那么权值和属性值会取最后一个索引中所存储的作为该文档ID的权值和属性值,用于排序、过滤,并返回给客户端(除非用SetIndexWeights()显式改变默认行为)。因此在上述示例中,索引“delta”中的匹配项总是比索引“main”中的更优先。
如果搜索成功,Query()
返回的结果集包含找到的全部匹配项中的一部分(根据SetLimits()之设定)和与查询相关的统计数据。结果集是hash(仅PHP,其他语言的API可能使用其他数据结构)
,包含如下键和值:
- "matches":
- 是一个hash表,存储文档ID以及其对应的另一个包含文档权重和属性值的hash表(或者是数组,如果启用了SetArrayResult())。
- "total":
- 此查询在服务器检索所得的匹配文档总数(即服务器端结果集的大小)。这是在当前设置下,用当前查询可以从服务器端获得的匹配文档数目的上限。
- "total_found":
- (服务器上找到和处理了的)索引中匹配文档的总数。
- "words":
- 一个hash,它将查询关键字(关键字已经过大小写转换,取词干和其他处理)映射到一个包含关于关键字的统计数据(“docs”——在多少文档中出现,“hits”——共出现了多少次)的小hash表上。
- "error":
searchd
报告的错误信息(人类可读的字符串)。若无错误则为空字符串。- "warning":
searchd
报告的警告信息(人类可读字符串)。若无警告则为空串。
需要指出的是Query()
索执行的操作,与没有中间步骤的AddQuery()
和RunQueries()
相同 ; 它类似一次单独的AddQuery()
调用,紧跟一次相应的RunQueries()
调用,然后返回匹配的第一个数组元素 (从第一次,也是仅有的一次查询返回)。
6.6.2.AddQuery (增加批量查询)
原型:function AddQuery ( $query, $index="*", $comment="" )
向批量查询增加一个查询。$query
为查询串。$index
为包含一个或多个索引名的字符串。 此外, 如果提供了$comment
,它 将被发送到查询日志中搜索部分的前面,这对于调试是非常有用的。目前,注释的长度限制为128个字符以内。返回RunQueries()返回的数组中的一个下标。
批量查询(或多查询)使searchd
能够进行可能的内部优化,并且无论在任何情况下都会减少网络连接和进程创建方面的开销。相对于单独的查询,批量查询不会引入任何额外的开销。因此当您的Web页运行几个不同的查询时,一定要考虑使用批量查询。
例如,多次运行同一个全文查询,但使用不同的排序或分组设置,这会使searchd
仅运行一次开销昂贵的全文检索和相关度计算,然后在此基础上产生多个分组结果。
有时您不仅需要简单地显示搜索结果,而且要显示一些与类别相关的计数信息,例如按制造商分组后的产品数目,此时批量查询会节约大量的开销。若无批量 查询,您会必须将这些本质上几乎相同的查询运行多次并取回相同的匹配项,最后产生不同的结果集。若使用批量查询,您只须将这些查询简单地组成一个批量查 询,Sphinx会在内部优化掉这些冗余的全文搜索。
AddQuery()
在内部存储全部当前设置状态以及查询,您也可在后续的AddQuery()
调用中改变设置。早先加入的查询不会被影响,实际上没有任何办法可以改变它们。下面是一个示例:
$cl->SetSortMode ( SPH_SORT_RELEVANCE ); $cl->AddQuery ( "hello world", "documents" ); $cl->SetSortMode ( SPH_SORT_ATTR_DESC, "price" ); $cl->AddQuery ( "ipod", "products" ); $cl->AddQuery ( "harry potter", "books" ); $results = $cl->RunQueries ();
用上述代码,第一个查询会在“documents”索引上查询“hello
world”并将结果按相关度排序,第二个查询会在“products”索引上查询“ipod”并将结果按价格排序,第三个查询在“books”索引上搜
索“harry potter”,结果仍按价格排序。注意,第二个SetSortMode()
调用并不会影响第一个查询(因为它已经被添加了),但后面的两个查询都会受影响。
此外,在AddQuery()
之前设置的任何过滤,都会被后续查询继续使用。因此,如果在第一个查询前使用SetFilter()
,则通过AddQuery()
执行的第二个查询(以及随后的批量查询)都会应用同样的过滤,除非你先调用ResetFilters()
来清除过滤规则。同时,你还可以随时加入新的过滤规则
AddQuery()
并不修改当前状态。也就是说,已有的全部排序、过滤和分组设置都不会因这个调用而发生改变,因此后续的查询很容易地复用现有设置。
AddQuery()
返回RunQueries()
结果返回的数组中的一个下标。它是一个从0开始的递增整数,即,第一次调用返回0,第二次返回1,以此类推。这个方便的特性使你在需要这些下标的时候不用手工记录它们。
6.6.3.RunQueries (执行批量查询)
原型:function RunQueries ()
连接到searchd,运行由AddQuery()
添加的全部查询,获取并返回它们的结果集。若发生一般错误(例如网络I/O失败)则返回假并设置GetLastError()
信息。若成功则返回结果集的简单数组。
该数组中的每一个结果集都跟Query()
返回的结果集完全相同。
注意,批量查询请求自身几乎总是成功——除非有网络错误、正在进行索引轮换,或者其他导致整个查询无法被处理的因素。
然而其中的单个的查询很可能失败。此时与之对应的结果集只包含一个非空的"error"
信息,而没有关于匹配或查询的统计信息。在极端情况下,批量查询中的所有单个查询可能都失败。但这仍然不会导致报告一般错误,因为API已经成功地连接到searchd
,提交了批量查询并得到返回结果——但每个结果集都只包含特定的错误信息。
6.6.4.ResetFilters (清除当前设置的过滤器)
原型:function ResetFilters ()
清除当前设置的过滤器。
通常此调用在使用批量查询的时候会用到。您可能需要为批量查询中的不同查询提供不同的过滤器,为达到这个目的,您需要调用ResetFilters()
然后用其他调用增加新的过滤器。
6.6.5.ResetGroupBy (清除现有的分组设置)
原型:function ResetGroupBy ()
清除现有的全部分组设置,并关闭分组。
通常此调用在使用批量查询的时候会用到。单独的分组设置可以用SetGroupBy()
和SetGroupDistinct()
来改变,但它们不能关闭分组。ResetGroupBy()
将之前的分组设置彻底重置并在当前状态下关闭分组模式,因此后续的AddQuery()
可以进行无分组的搜索。