import (
"github.com/gomodule/redigo/redis"
)
var redisPool *redis.Pool
func init() {
redisPool = &redis.Pool{
MaxIdle: 10,
MaxActive: 100,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "localhost:6379")
},
}
}
func recordUserView(user string, itemID int) error {
// 获取 Redis 连接
conn := redisPool.Get()
defer conn.Close()
// 将用户的浏览行为记录到位图中
_, err := conn.Do("SETBIT", fmt.Sprintf("item:%d:view", itemID), user, 1)
if err != nil {
return err
}
return nil
}
func getItemViewCount(itemID int) (int, error) {
// 获取 Redis 连接
conn := redisPool.Get()
defer conn.Close()
// 计算位图中为 1 的个数
count, err := redis.Int(conn.Do("BITCOUNT", fmt.Sprintf("item:%d:view", itemID)))
if err != nil {
return 0, err
}
return count, nil
}
例如商品a 被用户张三和李四访问了, 商品b 被张三访问了,这个时候访问量为2 , 张三访问了商品a,b 算1 , 李四访问了商品a 算1 ,合起来算2
如果说共同访问的人数,则吧 or 改成and ,算出来应该是1,只有张三访问了两个
func getTotalViewCount(itemIDs []int) (int, error) {
// 获取 Redis 连接
conn := redisPool.Get()
defer conn.Close()
// 将多个位图合并
args := make([]interface{}, len(itemIDs)+1)
args[0] = "OR"
for i, id := range itemIDs {
args[i+1] = fmt.Sprintf("item:%d:view", id)
}
_, err := conn.Do("BITOP", args...)
if err != nil {
return 0, err
}
// 计算位图中为 1 的个数
count, err := redis.Int(conn.Do("BITCOUNT", fmt.Sprintf("item:%d:view", itemIDs[0])))
if err != nil {
return 0, err
}
return count, nil
}