客串:屌丝的坑人表单神器php
走过的那些事儿:数据库那点事儿html
探讨:探讨负载均衡算法
面向对象的认识:面向对象的认识----新生的初识、面向对象的番外----思想的梦游篇(1)sql
起点:手把手教你作关键词匹配项目(搜索引擎)---- 第一天数据库
回顾:手把手教你作关键词匹配项目(搜索引擎)---- 第十八天负载均衡
第十九天post
上回咱们一直提到字典的构建,以及宝贝属性的特殊处理,提得太多,致使如今整个系统还不能彻底的运行起来。搜索引擎
小帅帅要多在这方面下功夫了。spa
就算上次咱们提到的用SQL语句里面的对属性LIKE,对黑名单NOT LIKE也没法解决全部的问题,咱们只是把须要匹配的关键词缩小了范围。code
咱们拿一个实例来讲明下:
有个宝贝是雪纺连衣裙,那么雪纺连衣裙a 、新潮雪纺连衣裙a、韩版雪纺女裙a、高仿雪纺女裙、正品女裙等这些词能用吗?
小帅帅、于老大、小乐乐、小欢欢以及小哼哼一致认为须要为每一个关键词跟宝贝属性(字典)作匹配,当匹配度处于某个值,好比>=80%的时候可用。
小帅帅又纳闷了,怎么作到为每一个关键词跟宝贝属性(字典)作匹配呢?
当时于老大就提到用关键词拆分算法,这个算法其实很简单,原理以下:
把关键词按业务词汇拆成词组或者单词,对每一个单词或者词组算出在整个关键词所占的比例,好比:雪纺连衣裙a 那么会被拆分红雪纺、连衣裙和a,那么相应的比例为33%、50%和17%。
而后再根据所拆成的词组或者单词同宝贝属性(字典)作对比,那么算出匹配成功的总比例来决定是否可用。好比宝贝是雪纺连衣裙,那么雪纺连衣裙a,所获得的匹配度为33%+50%=83%。
当这个算法一讲解完毕,小帅帅就迫不急待的写了代码,代码以下:
<?php class Splitter { /** * 获取类目下分词的词组数据,按字符串长度比较排序 * @param $cid * @return array */ public static function getWordSegmentation($cid){ $ret = array(); $sql = "select word from category_linklist where cid='$cid'"; $words = DB::makeArray($sql); foreach($words as $strWords){ $words = explode(",",$strWords); foreach($words as $word){ if(self::isPhrase($word)){ $ret[] = $word; } } } usort($ret,function($a,$b){ return (strlen($a)<strlen($b))?1:-1; }); return $ret; } /** * 检测是否为词组 * @param $word * @return bool */ public static function isPhrase($word){ if(preg_match('/^[\x{4E00}-\x{9FA5}]+$/u', $word) && strlen($word) <= 3){ return false; } if(strlen($word)<=1){ return false; } return true; } /** * 把关键词拆分红词组或者单词 * @param $keyword * @param $cid * @return array */ public static function split($keyword,$cid){ $splitWords = array(); $splitSegmentation = self::getWordSegmentation($cid); $remainKeyword = $keyword; foreach($splitSegmentation as $phrase){ if(count(explode($phrase,$remainKeyword))>1){ $splitWords[] = $phrase; $remainKeyword = str_replace($phrase,"::",$remainKeyword); } } $remainKeywords = explode("::",$remainKeyword); $splitWords = array_merge($splitWords,$remainKeywords); $keywordScores = array(); foreach($splitWords as $splitWord){ $keywordScore = new KeywordScore(); $keywordScore->splitWord = $splitWord; $keywordScore->weight = self::calculateWeight($splitWord,$keyword); $keywordScores[] = $keywordScore; } return $keywordScores; } /** * @desc 计算UTF8字符串权重 * @param string $splitWord * @param string $word * @return float */ public static function calculateWeight($splitWord, $word) { return ROUND(strlen($splitWord) / strlen($word), 3); } } class KeywordScore { public $splitWord; public $weight; }
小帅帅写这个也是一点一点通过屡次重构而得来的结果,他不想让于老大失望,因此一再精益求精。
小帅帅把代码拿给于老大看的时候,于老大会有什么反应呢,请看下回分解.