前面已经完成了分词和自动提示功能,最后把搜索结合在一起,来个完成的案例。当然最好还是用搜索分词解决,这个只是一个临时解决方案。
其实加上搜索很简单,要做的就是3件事
1. 分词的时候,把有用词的id存进hash.
2. 每次搜索的关键词,如果存在的自增
3. 通过关键词把hash里的 id取出,然后通过id查询数据库即可。
dist.php 分词
<?php require './redis.php'; //从数据库取出需要分词的数据 $words = [ ['name'=>'花讯','id'=>1], ['name'=>'nba','id'=>2], ['name'=>'nba直播','id'=>3], ['name'=>'nba赛事','id'=>4], ['name'=>'nba季后赛','id'=>5], ['name'=>'nba录像','id'=>6], ['name'=>'花讯品牌','id'=>7], ['name'=>'花讯女装','id'=>8], ['name'=>'花','id'=>9], ['name'=>'n','id'=>10], ['name'=>'nba直播','id'=>11], ]; //利用管道 Cache::getInstance()->pipeline(); foreach ($words as $val) { $len = mb_strlen($val['name'],'utf-8'); for ($i=0;$i<=$len;$i++){ $key = mb_substr($val['name'],0,$i+1,'utf-8'); if ($i == $len) { //所有相同关键词id $arr[$key][] = $val['id']; $key .= '*'; //初始化关键词搜索次数 Cache::getInstance()->hSet("search:hits",$key,0); } //分词加入有序集合 Cache::getInstance()->zAdd('search',0,$key); } } Cache::getInstance()->exec(); unset($words); //生成有用关键词hash表,用来存储id if (!empty($arr)) { array_walk($arr,function(&$v,$k){ $v = join(',',$v); }); Cache::getInstance()->hMset("search:ids",$arr); } echo 'ok';
search.php
<?php require './redis.php'; $key = isset($_GET['key']) ? $_GET['key'] : 'nba直' ; //如果存在 自增1 if (Cache::getInstance()->hGet("search:hits","{$key}*") !== false) Cache::getInstance()->hIncrBy("search:hits","{$key}*",1); //关键字开头存在有序集合的位置 $index = Cache::getInstance()->zRank('search',$key); if ($index === false) goto END; if ($_res = Cache::getInstance()->zRange('search',$index,-1)){ foreach ($_res as $val){ if (strpos($val,$key) === 0 && strrev($val)[0] == '*'){ $arr[] = substr($val,0,-1); } } //从hash表中获取id $res = Cache::getInstance()->hMGet("search:ids",$arr); //通过id 从mysql 获取数据源 echo 'ok'; } END:
4. 前端ajax请求获取数据渲染模板
完整代码: https://files.cnblogs.com/files/loveyouyou616/search.zip