redis使用bitop的一种业务场景

假设我们需要记录用户在电商平台上对某个商品的浏览行为,我们可以使用 Redis 的位图来记录。具体实现如下:

1. 创建一个 Redis 连接池
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")
        },
    }
}

2.定义一个函数来记录用户对商品的浏览行为
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
}

3.定义一个函数来计算某个商品的浏览人数
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
}

4. 定义一个函数来计算多个商品的浏览量人数之和

例如商品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
}

你可能感兴趣的:(golang,redis)