Sphinx添加了相当多的匹配和rank模式,并且将添加更多。一些不同的问题经常被提出,从“我怎样让指定的文档排在第一位”到 “我怎么根据匹配度来评定星级”,实际处理要归结于内在的匹配和排序。
匹配方式
匹配方式有基础匹配模式和拓展的匹配模式。
匹配本质
Sphinx 1.10版本中使用的两个最重要的权重因子是:
1)经典统计学BM25因子,从80年代开始被大部分的搜索引擎使用,
2)Sphinx特有的短语相似因子。
根据Sphinx排序使用的准确算法,可以通过调整字段权重微调排序。
虽然排序因子可能是整型,布尔型,浮点数或者其他任何可能的值,但权重值一定是个单标量值。在Sphinx里,权重值是一个整数,浮点数权重值可以通过各种各样方法映射到一个整数值。
匹配模式
SphinxAPI 提供两个不同的方法,分别是 MatchMode 和RankingMode。
MatchMode 匹配模式都是为了遗留和兼容。而RankingMode模式是关于Sphinx计算相关度的。
在版本0.9.8之前,Sphinx只有匹配模式,并且每个匹配模式是用不同的代码路径实现。每个代码路径实现一组不同类型的匹配和排序。例如,SPH_MATCH_ALL要求所有的关键字都出现,并且只用phrase proximity计算文档的权重。SPH_MATCH_ANY要求任何关键字中的一个,并且用不同的方式计算文档权重等等。
在版本0.9.8中,开始启用一个全新的,统一的匹配引擎。为了避免在使用它工作时破坏兼容性,在版本0.9.8中,只提供一个独立的匹配模式,叫做SPH_MATCH_EXTENDED2。到版本0.9.9时,显然新的引擎已经变的稳定并且表现的足够好,因而我们赞成从新引擎中移除所有遗留的代码路径。因此从版本0.9.9开始,所有的查询都用统一的引擎处理,这跟之前的情况不同,而且维护困难(指之前维护困难)。因此实际上现在所有的匹配模式都只是历史遗留。
当然Sphinx仍然继续兼容那些遗留的模式,并且当你使用其中的一种时,它会自动转换成一个简单的查询短语代码(完全忽略查询语法)然后自动选择一种适当的排序模式。但其实本来就是这样。一切都是由统一的引擎处理,因此,文档权重(即@weight)只跟选择的rank模式有关。
例如,下面两个查询将得到完全一样的权重(同样一样的处理时间):
// 1st route
$cl->SetMatchMode ( SPH_MATCH_ALL );
$cl->Query ( "helloworld" );
// 2nd route
$cl->SetMatchMode ( SPH_MATCH_EXTENDED2 );
$cl->SetRankingMode ( SPH_RANK_PROXIMITY );
$cl->Query ("helloworld" );
注意第二种方法允许使用(@titlehello world)语法,因为这种匹配模式允许这样做。第一种是不允许的,因为在那种匹配模式中所有的特殊操作符会被忽略,@title会被当成一个关键字。
MatchMode 功能是过滤关键字和选择一个合适的排序。它相当于一个历史调用,因为将不会再有新的匹配模式。
RankingMode只是让你明确的指定一个排序方式。
rank模式介绍
rank模式,或者简称排序,可以正式的定义成函数:对一个给定的查询和文档参数计算相关值(权重)。
相关度基本上是主观的,因此没有一个适合所有的排序模式,将来也不会有。因此有多个不同的因子用于计算最终的权重,有无数的方法合并这些因子为一个权重,讨论这些是另外单独帖子的主题。
匹配模式
以官方C的API为例,sphinx自带的一些匹配模式如下:
SPH_MATCH_ANY--匹配任意分词
匹配查询词中的任意一个。
通常想搜索到尽可能多的一句话中的内容,使用的是SPH_MATCH_ANY,但使用它之后,任何关键词中的字都可能做为一个单独的词进行搜索。这种匹配模式对词频也很有权重,这种搜索结果一般不是很准确
SPH_MATCH_PHRASE--匹配短语
将整个查询参数看作一个词组,要求按顺序完整匹配才会搜索出结果,搜索时会过滤掉特殊符号,比较符合需要搜索出相关度最高的结果。
在创建连接对象时,设置:
sphinx_client *client;
client->mode=SPH_MATCH_PHRASE;
SPH_MATCH_ALL--匹配所有查询词
匹配所有查询词(默认模式)
在创建连接对象时,设置:
sphinx_client * client;
client->mode= SPH_MATCH_ALL;
SPH_MATCH_BOOLEAN--布尔表达式
将查询看作一个布尔表达式
SPH_MATCH_EXTENDED--Sphinx内部查询语言的表达式
将查询看作一个Sphinx内部查询语言的表达式
SPH_MATCH_EXTENDED2--查询同时存在多个关键词
要搜索的关键词同时存在才会被搜索出来。因为SPHINX默认不是通过空格分词的。而是通过""来分。比如两个关键词:我们他是。
如果单这样写sphinx_query (client, “我们他是“, index, NULL );使用any模式会折成我 们 他 是 。似乎是一元分词法。而使用extended2则要搜索的字段同时存在这2个