版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013862108/article/details/83862649
类似 淘宝 比如 搜索框中输入 :书 :下拉框中出现:
'书包女士', '书包男款', '书大', '书包女赠送韩版', '书皮纸韩国小清新', '书斤', '书包女双肩包学生简约', '书双肩包', '书包学生', '书籍出版'
用户可以使用 上下箭头 或鼠标 选取
大致有两种思路:
一 使用一个有序集合 ;更节省内存; 使用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>';
}
}