類似 淘寶 比如 搜索框中輸入 :書 :下拉框中出現:
'書包女士', '書包男款', '書大', '書包女贈送韓版', '書皮紙韓國小清新', '書斤', '書包女雙肩包學生簡約', '書雙肩包', '書包學生', '書籍出版'
用戶可以使用 上下箭頭 或鼠標 選取
大致有兩種思路:
一 使用一個有序集合 ;更節省內存; 使用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>';
}
}