redis集合/有序集合在電商中應用-自動補全
阿新 • • 發佈:2018-11-11
類似 淘寶 比如 搜尋框中輸入 :書 :下拉框中出現:
'書包女士', '書包男款', '書大', '書包女贈送韓版', '書皮紙韓國小清新', '書斤', '書包女雙肩包學生簡約', '書雙肩包', '書包學生', '書籍出版'
使用者可以使用 上下箭頭 或滑鼠 選取
大致有兩種思路:
一 使用一個有序集合 ;更節省記憶體; 使用redis 對集合成員的預設排序(當元素的分數一樣時會按照元素值的字典順序排序);
二:使用多個集合(有序,無序都可以);可能更浪費記憶體,因為 像“書包女雙肩包學生簡約” 就在9個集合中都有;但是可以給標籤加score(權重);兩種方法各有優缺點:
程式碼如下:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Tag extends CI_Controller { public function index() { $this->load->library('predis'); $this->load->view('welcome_message'); } public function tag_data(){ //標籤資料 //資料從淘寶找的 //生產中資料可以從MySQL中獲取 $tag_data = array( '書包女士', '書包男款', '書大', '書包女贈送韓版', '書皮紙韓國小清新', '書斤', '書包女雙肩包學生簡約', '書雙肩包', '書包學生', '書籍出版' ); return $tag_data; } /** * @param $word 要拆分的標籤 * 如 :$word == '書包女士' * 將拆分為 : 書 書包 書包 書包女 書包女士* * * 作用標記完整標籤,當前也可以使用如# $這樣的標籤; */ public function get_prefixes($word){ $arr = array(); echo $length = mb_strlen($word,'utf8'); for($i = 1; $i<= $length; $i++){ $item = mb_substr($word,0,$i); if($i == $length){ array_push($arr,$item.'*'); }else{ array_push($arr,$item); } } return $arr; } public function ready_autocomplete(){ $tag_arr = $this->tag_data(); foreach ($tag_arr as $val){ $item = $this->get_prefixes($val); foreach ($item as $word){ //array_push($argv,array(0,$word)); $this->predis->zadd('autocomplete',0,$word); } } } public function view_autocomplete(){ $autocomplete = $this->predis->zrange('autocomplete',0,-1); echo 'autocomplete'; echo '<pre>'; var_dump($autocomplete); echo '</pre>'; } public function is_exists_mbstrlen(){ echo function_exists('mb_strlen'); } public function test(){ $input = $this->input->get('input',true); //zrank 返回有序集合key 中成員member的排名; 排名從0開始 $zrank = $this->predis->zrank('autocomplete',$input); // echo 'zrank:'; var_dump($zrank); if(isset($zrank)){ $values = $this->predis->zrange('autocomplete',$zrank,$zrank+100); echo 'values:'; var_dump($values); foreach ($values as $val){ if(mb_substr($val,mb_strlen($val)-1) == '*' && $input == mb_substr($val,0,mb_strlen($input))){ echo mb_substr($val,0,mb_strlen($val)-1)."<br/>"; } } } } /** * 第二種方法, 標籤, * 如 書包男款 被拆集合鍵(有序,無序都可以)為: 書 書包 書包男; 每一個都是集合 * 有序集合鍵可以 利用 sort 配合by 把最熱門的標籤排在前面 * * 兩種方法對比 :第一種使用一個集合 更節省記憶體; 第二種;使用多個集合 可以給完整標籤設定分數,給標籤加權重。各有優缺點 */ public function ready2(){ $tag_arr = $this->tag_data(); if(!empty($tag_arr) && is_array($tag_arr)){ foreach($tag_arr as $key=>$val){ $this->tagSet2($val); } } } /** * @param $tag * 將標籤存入集合 */ public function tagSet2($tag){ echo $length = mb_strlen($tag,'utf8'); for($i = 1; $i< $length; $i++){ $key = mb_substr($tag,0,$i); //$this->predis->sadd($key,$tag); $score = mt_rand(0,100); $this->predis->zadd($key,$score,$tag); } } public function test2(){ $input = $this->input->get('input',true); //$members = $this->predis->smembers($input); //$members = $this->predis->zrange($input,0,-1,'withscores'); //帶排序 $members = $this->predis->zrevrangebyscore($input,'+inf',0,'withscores','limit',0,3); echo '<pre>'; var_dump($members); echo '</pre>'; } }