sphinx搜索结果按权重排序php,用 Sphinx 简单实现无插件的中文搜索+拼音搜索

市面上的全文搜索引擎非常多,但通常想要支持中文搜索和拼音搜索都挺费力的。又是下载编译安装,又是装插件扩展,挺烦的。

我用 Sphinx 研究出了一种可以不用任何扩展,就能支持中文搜索+拼音搜索的解决方案。性能没差,效果也不差,一般不追求完美的已经足够了。

通常搜索引擎因为都是老外开发的,而欧美国家的词语,一般都是用空格分隔,所以很好做分词。而亚洲文字就比较尴尬了,连续的并没有分隔符,这样文字的分词就是一个大问题。

所以想要让搜索引擎支持中文搜索,首先要解决分词问题。比如我想到的就是把一串中文转为英文,存入文本索引,这样搜索引擎就可以识别了。/**

* 编码sphinx中文存储

* @param string $str

* @return string

*/

function encodeSphinxChinese($str)

{

return str_replace('\\', '%', substr(json_encode($str), 1, -1));

}

如上代码,我是用的将字符串转为 unicode 格式,sphinx建索引和搜索时候,都要将搜索词编码后才可以匹配结果。

那下面来说说拼音搜索的实现,要实现拼音搜索,就要先将中文翻译成拼音。考虑到多音字的情况,我将所有可能性的拼音都建进sphinx的索引里了。这里使用的是我开源的

比如将“我的”转换为拼音后,得到两个结果:“wo de”和“wo di”,将他们都存入文本索引。

拼音索引问题解决,那接下来就是搜索的时候了。用户搜索拼音,不可能给你按空格,很有可能输入的是“wode”,那这时候是匹配不到的。这时候需要进行拼音分词。

比如用户输入“xianggang”,拼音分词后得到2个结果:“xi ang gang”和“xiang gang”,这时候处理搜索接口时候,需要将这两个词都作为搜索词。

然后通过PHP代码,将返回的搜索结果进行合并和权重排序。$sc = new SphinxClient;

// 这里做一些其它事,省略

$results = $sc->RunQueries();

if(false === $results)

{

throw new Exception(mb_convert_encoding($sc->GetLastError(), 'UTF-8', 'GBK'));

}

$totalFound = 0;

$matches = array();

foreach($results as $item)

{

if(!empty($item['error']))

{

throw new Exception($item['error']);

}

$totalFound += $item['total_found'];

if(!empty($item['matches']))

{

foreach($item['matches'] as $id => $match)

{

if(!isset($matches[$id]))

{

$matches[$id] = [];

}

if(isset($matches[$id]['count']))

{

++$matches[$id]['count'];

}

else

{

$matches[$id]['count'] = 2;

}

$matches[$id]['weight'] += $match['weight'];

}

}

}

unset($results);

uasort($matches, function(&$a, &$b){

if(isset($a['count']))

{

$a['weight'] /= $a['count'];

unset($a['count']);

}

if(isset($b['count']))

{

$b['weight'] /= $b['count'];

unset($b['count']);

}

if($a['weight'] === $b['weight'])

{

return 0;

}

else

{

return $a['weight'] > $b['weight'] ? -1 : 1;

}

});

$matches = array_keys($matches);

if(null === $limit)

{

return $matches;

}

else

{

return array_splice($matches, 0, $limit);

}

最终的查询结果,不追求完美的也可以了,当然还有一些不是很严重的缺陷。本文仅提供一种思路,并不代表是最佳解决方案。代码单纯复制粘贴无用,仅作参考!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值