自动补全与输入联想功能已经是大多数网站的标配,给表单加入自动补全功能大大节省了用户输入时间,而输入联想功能则起到了预测用户喜好的作用,两个功能都是提升用户体验的利器。
本实训,我们通过实现搜索历史、自动补全和搜索预测三大常用功能,带领大家编写实用的程序组件。
搜索历史功能
#!/usr/bin/env python
#-*- coding:utf-8 -*-import redisconn = redis.Redis()# 将最新搜索词记录到搜索记录列表中
def add_search_history(user_id, keyword):# 将最新搜索词记录到指定用户的搜索记录列表中# user_id: 用户ID# keyword: 搜索关键词history_list = "recent:search:" + user_idpipe = conn.pipeline()pipe.multi()pipe.lrem(history_list, 0, keyword) # 移除已存在的关键词pipe.lpush(history_list, keyword) # 将关键词插入到列表头部pipe.ltrim(history_list, 0, 49) # 保留最新的50个搜索记录pipe.execute()# 删除搜索记录列表中的指定搜索词
def remove_search_history(user_id, keyword):# 从指定用户的搜索记录列表中删除指定的搜索词# user_id: 用户ID# keyword: 待删除的搜索关键词conn.lrem("recent:search:" + user_id, 0, keyword)# 获取到自动匹配的搜索词列表
def fetch_autocomplete_list(user_id, prefix):# 获取指定用户搜索记录列表中以指定前缀开头的搜索词列表# user_id: 用户ID# prefix: 搜索关键词前缀candidates = conn.lrange("recent:search:" + user_id, 0, -1)matches = [candidate.decode('utf-8') for candidate in candidates if candidate.decode('utf-8').startswith(prefix)]return matches
自动补全功能
#!/usr/bin/env python
#-*- coding:utf-8 -*-import uuid
import redis
import bisectconn = redis.Redis()# 生成起始元素和结束元素
def find_prefix_range(prefix):# 根据前缀生成起始元素和结束元素,用于查找匹配的提示词# prefix: 给定的前缀字符串characters = "`abcdefghijklmnopqrstuvwxyz{"posn = bisect.bisect_left(characters, prefix[-1:])suffix = characters[(posn or 1) - 1]return prefix[:-1] + suffix + '{', prefix + '{'# 获取匹配提示词列表
def autocomplete_on_prefix(prefix):# 根据前缀获取匹配的提示词列表# prefix: 给定的前缀字符串zset_name = 'autocomplete:candidates'start, end = find_prefix_range(prefix)identifier = str(uuid.uuid4())start += identifierend += identifierconn.zadd(zset_name, {start: 0, end: 0})sindex = conn.zrank(zset_name, start)eindex = conn.zrank(zset_name, end)erange = min(sindex + 9, eindex - 2)pipe = conn.pipeline()pipe.multi()pipe.zrem(zset_name, start, end)pipe.zrange(zset_name, sindex, erange)items = pipe.execute()[-1]return [item for item in items if '{' not in item]
搜索预测功能
#!/usr/bin/env python
#-*- coding:utf-8 -*-import redisconn = redis.Redis()# 记录搜索词频次
def add_keyword_frequency(keyword):# 根据搜索词记录频次并维护搜索词的有序集合# keyword: 搜索词for i in range(len(keyword)):zset_name = "keyword:" + keyword[0:i+1]conn.zincrby(zset_name, 1, keyword)conn.zremrangebyrank(zset_name, 20, -1)conn.expire(zset_name, 86400)# 获取搜索预测列表
def get_search_suggestions(prefix):# 根据前缀获取搜索预测列表# prefix: 搜索词前缀return conn.zrevrange("keyword:" + prefix, 0, -1)