redis实战:使用redis实现自动补全

来源:互联网 发布:淘宝哪里自助开通 编辑:程序博客网 时间:2024/06/07 00:09

转载:http://blog.csdn.net/u011250882/article/details/48632379

如果我想输入“雄英”来找到游戏库中的所有带有这两个字的游戏,该怎样用redis来实现呢?

原理:

1, 将所有的游戏名字读出来,拆分成单个汉字

2, 将这些汉字作为redis集合的键,写入redis,每个集合里的值是所有那些游戏名字中包含此汉字的游戏的id

3, 当用户输入文字的时候通过ajax异步请求,将用户输入传给PHP

4, 将输入的文字拆分成单个汉字, 分别找到这些汉字在redis中的集合值

5, 取出来,求交集,就找到了同时包含这几个汉字的游戏的id

6, 最后到数据库里查出来相应的游戏信息即可

缺点: 删除数据不方便


具体实现代码:

redis代码:iredis.php

[php] view plain copy
  1. <?php  
  2. class iRedis extends Redis{  
  3.   
  4.     public function __construct(){  
  5.         $this->connect('127.0.0.1', 6379);  
  6.     }  
  7.   
  8.     //获取某个key之下的redis数据  
  9.     public function getIndex($key){  
  10.         return $this->sMembers($key);  
  11.     }  
  12.   
  13.     //删除某个key之下的redis数据  
  14.     public function delIndex($key){  
  15.         return $this->sMembers($key);  
  16.     }  
  17.       
  18. }  

game模型类代码:

[php] view plain copy
  1. <?php   
  2. require_once 'database.php';  
  3. require_once 'iredis.php';  
  4. class Game extends Database{  
  5.   
  6.     public $instance;  
  7.   
  8.     public $redis;  
  9.   
  10.     public $table = 'game';  
  11.   
  12.     public function __construct(){  
  13.         $this->instance = self::getInstance();  
  14.         $this->redis = new iRedis();  
  15.     }  
  16.   
  17.     //为游戏创建索引  
  18.     public function createIndexes(){  
  19.         $sql = "select * from $this->table";  
  20.         $games = $this->instance->query($sql)->fetch_all(MYSQLI_ASSOC);  
  21.         $splitedGames = $this->splitGameName($games);  
  22.         foreach($splitedGames as $k => $v){  
  23.             $this->redis->sAdd($k, serialize($v));  
  24.         }  
  25.     }  
  26.   
  27.     //根据id获取游戏名  
  28.     public function getGameByGameid($gameid){  
  29.         $gameidStr = implode(','$gameid);  
  30.         $sql = "select name from $this->table where id in ($gameidStr)";  
  31.         $gameName = $this->instance->query($sql)->fetch_all(MYSQLI_ASSOC);  
  32.         return $gameName;  
  33.     }  
  34.   
  35.     //根据用户输入获取提示信息  
  36.     public function getHint($keyword){  
  37.         if(empty($keyword)){  
  38.             return "";                
  39.         }  
  40.   
  41.         if(mb_strlen($keyword'utf-8') == 1){  
  42.             // $gameids = unserialize($this->redis->getIndex($keyword));  
  43.             $unserializedGameids = $this->redis->getIndex($keyword);  
  44.             $gameids = unserialize($unserializedGameids[0]);  
  45.             if(empty($gameids) || !is_array($gameids)){  
  46.                 return "";  
  47.             }  
  48.             return $this->getGameByGameid($gameids);  
  49.         }  
  50.   
  51.         $gameids = array();  
  52.         $keywordLenth = mb_strlen($keyword'utf-8');  
  53.         for ($i = 0; $i < $keywordLenth$i++) {   
  54.             $keywordPiece = mb_substr($keyword$i, 1, 'utf-8');  
  55.             $unserializedGameids = $this->redis->getIndex($keywordPiece);  
  56.             $gameid = unserialize($unserializedGameids[0]);  
  57.             if(!empty($gameid)){  
  58.                 $gameids = empty($gameids) ? $gameid : array_intersect($gameids$gameid);  
  59.             }  
  60.         }  
  61.   
  62.         if(empty($gameids) || !is_array($gameids)){  
  63.                 return "";  
  64.         }  
  65.         return $this->getGameByGameid($gameids);  
  66.   
  67.     }  
  68.   
  69.     //将游戏名进行拆分  
  70.     private function splitGameName($games){  
  71.         $splitedGames = array();  
  72.         foreach ($games as $game) {  
  73.             $ganeNameLenth = mb_strlen($game['name'], 'utf-8');  
  74.             for ($i = 0; $i < $ganeNameLenth$i++) {   
  75.                 $gameNamePiece = mb_substr($game['name'], $i, 1, 'utf-8');  
  76.                 $splitedGames[$gameNamePiece][] = $game['id'];  
  77.             }  
  78.         }  
  79.         return $splitedGames;  
  80.     }  
  81.   
  82. }  

database.php

[php] view plain copy
  1. <?php   
  2. class Database{  
  3.     //只是为了演示,通常情况下数据库的配置是会单独写在配置文件中的  
  4.     private static $_dbConfig = array(  
  5.         'host' => '127.0.0.1',  
  6.         'username' => 'root',  
  7.         'pwd' => '',  
  8.         'dbname' => 'bussiness'  
  9.         );  
  10.   
  11.     private static $_instance;  
  12.   
  13.     public static function getInstance(){  
  14.         if(is_null(self::$_instance)){  
  15.             self::$_instance = new mysqli(self::$_dbConfig['host'], self::$_dbConfig['username'], self::$_dbConfig['pwd'], self::$_dbConfig['dbname']);   
  16.             if(self::$_instance->connect_errno){  
  17.                 throw new Exception(self::$_instance->connect_error);  
  18.             }  
  19.         }  
  20.         return self::$_instance;  
  21.     }  
  22.   
  23.   
  24. }  

index.php

[php] view plain copy
  1. <?php   
  2. require_once 'game.php';  
  3. require_once 'iredis.php';  
  4.   
  5. $redis = new iRedis();  
  6. $game = new Game();  
  7. $game->createIndexes();  
  8. var_dump($game->getHint('雄英'));  

数据库中game表中的测试数据入下截图所示:


执行index.php中的代码结果如下图所示:


点评:可以进一步修改,直接使用redis自身的功能求交集。


0 0
原创粉丝点击