Go 对ZSet操作,go使用zset实现排行榜。go单元测试模拟redis

Go 对ZSet操作

redis client操作使用 https://github.com/go-redis/redis

创建可以这样:

RedisClient := redis.NewClient(&redis.Options{
		Addr:         c.Addr,
		Password:     c.Password,
		DB:           c.DB,
		MinIdleConns: c.MinIdleConn,
		DialTimeout:  c.DialTimeout,
		ReadTimeout:  c.ReadTimeout,
		WriteTimeout: c.WriteTimeout,
		PoolSize:     c.PoolSize,
		PoolTimeout:  c.PoolTimeout,
	})

单元测试模拟 redis使用 https://github.com/alicebob/miniredis

func InitTestRedis() {
	mr, err := miniredis.Run()
	if err != nil {
		panic(err)
	}
	// 打开下面命令可以测试链接关闭的情况
	// defer mr.Close()

	RedisClient = redis.NewClient(&redis.Options{
		Addr: mr.Addr(),
	})
	fmt.Println("mini redis addr:", mr.Addr())
}

ZSet操作

func TestRedisZSet(t *testing.T) {
	InitTestRedis()
	ctx := context.Background()
	ls := []*redis.Z{
		{Score: 90.0, Member: "one"},
		{Score: 80.0, Member: "two"},
		{Score: 70.0, Member: "three"},
		{Score: 60.0, Member: "four"},
		{Score: 50.0, Member: "five"},
	}
	cli := RedisClient
	l1 := redis.Z{
		Score:  40,
		Member: "six",
	}

	// 添加一个值
	cli.ZAdd(ctx, "ranking", &l1)
	cli.ZAdd(ctx, "ranking", ls...)
	//升序:查询zset中指定区间的成员,-1代表取到最后
	println("=====================")
	println("升序获取到倒数第三-->")
	fmt.Println("ZRange:", cli.ZRange(ctx, "ranking", 0, 3).Val()) //[six five four three]
	//降序:查询zset中指定区间的成员,-1代表取到最后
	println("=====================")
	println("降序获取所有-->")
	fmt.Println("ZRevRange:", cli.ZRevRange(ctx, "ranking", 0, -1).Val()) // [one two three four five six]

	// [six five four three two one]
	opt := redis.ZRangeBy{
		Min:    "50", //最小分数
		Max:    "90", //最大分数
		Offset: 2,    //在满足条件的范围,从offset下标处开始取值
		Count:  3,    //查询结果集个数
	}
	//升序:根据opt条件查询Member成员
	println("=====================")
	println("条件查询 获取50-90分数区间,升序找到3个结果,-->")
	fmt.Println(cli.ZRangeByScore(ctx, "ranking", &opt).Val()) // [three two one]
	//降序:根据opt条件查询Member成员
	println("条件查询 获取50-90分数区间,降序找到3个结果,-->")
	fmt.Println(cli.ZRevRangeByScore(ctx, "ranking", &opt).Val()) //[three four five]

	//升序:根据下标范围返回的redis.Z结构体切片
	println("=====================")
	println("条件查询 从小到大,获取0-3名次,-->")
	fmt.Println(cli.ZRangeWithScores(ctx, "ranking", 0, 3).Val()) //[{40 six} {50 five} {60 four} {70 three}]
	//降序:根据下标范围返回的redis.Z结构体切片
	println("条件查询 从大到小,获取所有名次,-->")
	fmt.Println(cli.ZRevRangeWithScores(ctx, "ranking", 0, -1).Val()) //[{90 one} {80 two} {70 three} {60 four} {50 five} {40 six}]

	//升序:根据opt条件,返回的redis.Z结构体切片
	println("=====================")
	println("条件查询 获取50-90分数区间,升序找到3个结果集,-->")
	fmt.Println(cli.ZRangeByScoreWithScores(ctx, "ranking", &opt).Val())
	//降序:根据opt条件,返回的redis.Z结构体切片
	println("条件查询 获取50-90分数区间,降序找到3个结果集,-->")
	fmt.Println(cli.ZRevRangeByScoreWithScores(ctx, "ranking", &opt).Val())

	//fmt.Println(cli.ZRangeByLex(ctx, "ranking", &opt).Val())
	//fmt.Println(cli.ZRevRangeByLex(ctx, "ranking", &opt).Val())

	// 获取指定成员的score
	println("=====================")
	println("获取指定成员5分数,-->")
	f := cli.ZScore(ctx, "ranking", "5").Val()
	fmt.Println(f) // 80

	// 获取指定成员的下标
	println("获取指定成员5下标,-->")
	fmt.Println(cli.ZRank(ctx, "ranking", "5").Val()) //3

	// 返回指定区间的成员个数
	fmt.Println("获取50-80分数区间成员人数,-->")
	fmt.Println(cli.ZCount(ctx, "ranking", "50", "80").Val()) //4

	// 返回集合中成员的个数
	println("获取总榜成员人数,-->")
	fmt.Println(cli.ZCard(ctx, "ranking").Val()) //6

	// 根据成员名称,移除指定成员(可以多个): 0:失败  0<:成功
	println("移除不存在的成员,-->")
	fmt.Println(cli.ZRem(ctx, "ranking", "c++").Val()) //0
	println("移除存在的成员,-->")
	fmt.Println(cli.ZRem(ctx, "ranking", "six", "one").Val()) //2
	println("打印现存的所有成员-->")
	fmt.Println(cli.ZRange(ctx, "ranking", 0, -1).Val()) // [five four three two]
	// 升序:根据下标区间移除指定成员
	println("移除下标1-2的成员-->")
	fmt.Println(cli.ZRemRangeByRank(ctx, "ranking", 1, 2).Val()) //2:表示移除了两个
	println("打印现存的所有成员-->")
	fmt.Println(cli.ZRangeWithScores(ctx, "ranking", 0, -1).Val()) // [{50 five} {80 two}]
	// 升序:根据分数区间移除指定成员
	println("移除70-90分间的成员-->")
	fmt.Println(cli.ZRemRangeByScore(ctx, "ranking", "70", "90").Val()) //1:表示移除了一个
	println("打印现存的所有成员-->")
	fmt.Println(cli.ZRangeWithScores(ctx, "ranking", 0, -1).Val()) // [{50 five}]
}

版权声明:本文为w_monster原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。