自动完成功能一般都伴随搜索框出现,就是用户在输入时帮助其自动补全。

比如对成语进行补全,现有如下成语:一心一意,一心二用,一帆风顺。

两种实现方式:

实现方式一:

为每个成语的每个前缀都使用一个集合类型键来存储该前缀对应的成语名,并且为了实现排序,我们使用有序集合,并score都为0,这样就按元素值的字典序排序。如果想要实现按照词的热度排序,需要再创建一个有序集合,存放词和score,最后把查询结果和这个集合做交集即可,这样可以避免更新一个词的热度需要更新多个集合的情况,因为一个词会出现在多个集合中。

做法:

对于上边的成语就会创建如下形式的有序集合(key : value,...),score都为0:

一 :一心一意,一心二用,一帆风顺

一心:一心一意,一心二用

一心一:一心一意

一心二:一心二用

一帆:一帆风顺

一帆风:一帆风顺

下边实现生成这些前缀对应的有序集合的代码

$valueArr = ['一心一意','一心二用','一帆风顺'];
//中文字符注意指定编码,不能用$str[$i]方式获取中文
foreach ($valueArr as $item) {
for ($i = 1,$len = mb_strlen($item, "utf-8"); $i < $len; $i++) {
$k = $prefix.mb_substr($item,0, $i, "utf-8");
$redis->zadd($k, 0, $item);
}
}

在通过对应的关键字获取对应的有序集合即可

$search1 = "一";
$search2 = "一帆";
$ret1 = $redis->zRange($$prefix.$search1, 0, -1);
$ret2 = $redis->zRange($$prefix.$search2, 0, -1);

如果需要实现热度排序,只需要取关键字集合和全部成语的热度集合的交集即可,通过参数指定两个集合的分数组合方式

$redis->zInter($retZset, [$prefix.$search, $hotZset]); //取交集
$ret = $redis->zRevRange($retZset, 0, -1); //倒序

实现方式二:

通过有序集合实现,该方法由redis作者介绍。因为有序集合当元素的score相同时,按照元素的字典序排序,利用这个特性只用一个有序集合就能实现标签补全。

做法:

把全部成语前缀存入有序集合,再把全部成语后边加上*号后存入有序集合,分数均为0。

获取时先取关键字在zset中的排名,然后在获取排名后的N个元素,最后遍历结果,找出*结尾并且以对应关键字开头的元素即是结果。

先实现存入代码

//遍历全部的前缀和成语加入有序集合
foreach ($valueArr as $item) {
for ($i = 1,$len = mb_strlen($item, "utf-8"); $i <= $len; $i++) {
$member = mb_substr($item,0, $i, "utf-8");
if ($i == $len) {
$member .= "*"; //非前缀需要在后边补*
}
$redis->zadd("auto:zset", 0, $member);
}
}

再实现获取代码

//查询
$search = "一帆";
$rank = $redis->zRank("auto:zset", $search);
$ret = $redis->zRange("auto:zset", $rank + 1, $rank + 10); //获取10个
$ret = array_filter($ret, function($d){
return ("*" === mb_substr($d, -1)); //此处没有去掉*,没有匹配前缀,多出来不匹配条数可以作为推荐
});
echo "<pre>";print_r($ret);exit;

总结:

方式一需要N个集合存储,但每个集合数据量较小,方式二只用一个集合实现,但数据量大,同时实现热度排序比较困难,这个看具体使用场景和数据量选择吧。

redis技巧--自动完成功能实现的更多相关文章

  1. 通过Keepalived实现Redis Failover自动故障切换功能

    通过Keepalived实现Redis Failover自动故障切换功能[实践分享] 参考资料: http://patrick-tang.blogspot.com/2012/06/redis-keep ...

  2. 利用redis完成自动补全搜索功能(三)

    前面已经完成了分词和自动提示功能,最后把搜索结合在一起,来个完成的案例.当然最好还是用搜索分词解决,这个只是一个临时解决方案. 其实加上搜索很简单,要做的就是3件事 1. 分词的时候,把有用词的id存 ...

  3. Java初学者不可不知的MyEclipse的设置技巧(自动联想功能)

    最近初学Java,正在使用MyEclipse来编写新的项目,刚开始打开MyEclipse感觉这个工具既陌生又熟悉,熟悉之处在于编辑器的几大共通之处它都具备,比如说基本的设置.编辑区.调试区都是类似的, ...

  4. sql server小技巧-自动添加时间与主键自增长

    在敲机房收费系统的时候,遇到添加时间的时候总是通过vb端调用当前时间再添到sql server中,期间还有时因为添加时间格式的不统一导致一些小问题,现在才知道原来是自己孤陋寡闻,sql server ...

  5. 让zend studio 支持 redis函数自动提示

    phpredis作者https://github.com/nicolasff/phpredis 写了文档https://github.com/ukko/phpredis-phpdoc上面提到了如何让e ...

  6. redis实现自动输入完成(八)

    1. 介绍 当我们在京东商城的搜索框,输入想要搜索的内容,比如你想要搜索"热水瓶",刚输入一个"热"字,就会出现一个下拉框,列出了很多以"热" ...

  7. 怎么用Folx自动标签功能自动分类文件

    Folx标签功能可以帮助职场人士提高文件分类的效率.通过使用自动标签功能,用户可以在文件下载时,自动为相关的文件进行标签分类.接下来,小编会以创建"软件"自动标签为例,为大家演示相 ...

  8. 基于JQuery实现的文本框自动填充功能

    1. 实现的方法 /* * js实现的文本框的自动完成功能 */ function doAutoComplete(textid,dataid,url){ $("#" + texti ...

  9. eclipse自动提示功能没了的解决办法(转载)

    eclipse自动提示功能没了的解决办法 标签: eclipse联想 2012-08-09 14:32 24687人阅读 评论(7) 收藏 举报  分类: Android(38)  版权声明:本文为博 ...

随机推荐

  1. MVC View中获取action、controller、area名称

    获取控制器名称: ViewContext.RouteData.Values["controller"].ToString(); 获取Action名称: ViewContext.Ro ...

  2. 感受C# 的魅力,将一坨代码写成一行

    摘自MSDN :https://msdn.microsoft.com/zh-cn/library/bb549151(v=vs.100).aspx 1.平时定义一个委托 using System; // ...

  3. 读取properties配置文件的方法

    一般在.properties文件中配置数据库连接的相关信息,我们需要从中读取信息,以便建立与数据库的连接. 文件目录: application.properties配置信息: url=jdbc:ora ...

  4. redis数据结构存储Linked List设计细节(redis的设计与实现笔记)

    redis里拥有一个灵活扩展且获取表头表尾复杂度为O(1)的双端列表,分为list和listNode2部分组成. list: typedef struct list {//链表 listNode *h ...

  5. Python学习笔记5-闭合与生成器

    >>> import re >>> re.search('[abc]','mark') <_sre.SRE_Match object; span=(1, 2) ...

  6. 昨天写支付接口时遇到支付接口返回数据接收地址,session数据丢失(或者说失效)的问题

    在网上找了好久 才找到答案 分享给大家 http://www.zcool.com.cn/article/ZMzYwNTI=.html

  7. shell 脚本之 shell 练习题汇总

    整理了一些 shell 相关的练习题,记录到这里. 1. 请按照这样的日期格式 xxxx-xx-xx 每日生成一个文件,例如:今天生成的文件为 2013-09-23.log, 并且把磁盘的使用情况写到 ...

  8. how2heap分析系列:0

    新学期到了,给学弟们写点东西, https://github.com/shellphish/how2heap 这个how2heap挺不错的,讲述了heap上几种不同的漏洞利用技术,在后面发的几篇中我会 ...

  9. 【C】.h头文件的重复包含问题

    .h头文件存在的意义就是封装,可以方便多个.c源文件使用,但要防止.h头文件被同一个.c源文件多次包含. 例如, io.h文件 #ifndef _IO_H_ #define _IO_H_ #defin ...

  10. uva 1599 ideal path(好题)——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGYAAAODCAYAAAD+ZwdMAAAgAElEQVR4nOy9L8/0ypH/Pa8givGiyC