go-redis使用之ZSet有序集合

于飞飙
2023-12-01

go-redis ZSet有序集合操作

->go-redis String字符串使用详解
->go-redis List列表使用详解
->go-redis Hash哈希使用详解
->go-redis Set集合使用详解

ZSet(sorted set):有序不重复集合

ZSet的每个元素都会关联一个float64类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为2的32次方 - 1

  

func GetRedisClient() *redis.Client {
	return redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
}

// redisZsetTest Zset(sorted set有序不重复集合)
func redisZsetTest(cli *redis.Client){

	lang := []redis.Z{
		redis.Z{Score: 90.0, Member: "java"},
		redis.Z{Score: 80.0, Member: "go"},
		redis.Z{Score: 70.0, Member: "python"},
		redis.Z{Score: 60.0, Member: "php"},
		redis.Z{Score: 50.0, Member: "ruby"},
	}

	l1:= struct {
		Score  float64
		Member interface{}
	}{
		40,
		"javaScript",
	}

	//l2 :=redis.Z{
	//	Score:  30,
	//	Member: "Object-C",
	//}

	// 添加一个值
	cli.ZAdd("lang",l1)
	// 添加多个值
	_,err:=cli.ZAdd("lang",lang...).Result()
	if err != nil {
		panic(err)
	}
	//升序:查询zset中指定区间的成员,-1代表取到最后
	fmt.Println("ZRange:",cli.ZRange("lang",0,3).Val())		//[javaScript ruby php python]
	//降序:查询zset中指定区间的成员,-1代表取到最后
	fmt.Println("ZRevRange:",cli.ZRevRange("lang",0,-1).Val())	// [java go python php ruby javaScript]

	// [Go javaScript ruby php python go java]
	opt:=redis.ZRangeBy{
		Min:    "50",	//最小分数
		Max:    "90",	//最大分数
		Offset: 2,		//在满足条件的范围,从offset下标处开始取值
		Count:  3,		//查询结果集个数
	}
	//升序:根据opt条件查询Member成员
	fmt.Println(cli.ZRangeByScore("lang",opt).Val())	// [python go java]
	//降序:根据opt条件查询Member成员
	fmt.Println(cli.ZRevRangeByScore("lang",opt).Val())	//[python php ruby]

	//升序:根据下标范围返回的redis.Z结构体切片
	fmt.Println(cli.ZRangeWithScores("lang",0,3).Val())	//[{40 javaScript} {50 ruby} {60 php} {70 python}]
	//降序:根据下标范围返回的redis.Z结构体切片
	fmt.Println(cli.ZRevRangeWithScores("lang",0,-1).Val())//[{90 java} {80 go} {70 python} {60 php} {50 ruby} {40 javaScript}]

	//升序:根据opt条件,返回的redis.Z结构体切片
	fmt.Println(cli.ZRangeByScoreWithScores("lang",opt).Val())
	//降序:根据opt条件,返回的redis.Z结构体切片
	fmt.Println(cli.ZRevRangeByScoreWithScores("lang",opt).Val())

	fmt.Println(cli.ZRangeByLex("lang",opt).Val())
	fmt.Println(cli.ZRevRangeByLex("lang",opt).Val())

	// 获取指定成员的score
	f:=cli.ZScore("lang","go").Val()
	fmt.Println(f)	// 80

	// 获取指定成员的下标
	fmt.Println(cli.ZRank("lang","python").Val())	//3

	// 返回指定区间的成员个数
	fmt.Println(cli.ZCount("lang","50","80").Val())//4

	// 返回集合中成员的个数
	fmt.Println(cli.ZCard("lang").Val())	//6

	// 根据成员名称,移除指定成员(可以多个): 0:失败  0<:成功
	fmt.Println(cli.ZRem("lang","c++").Val())//0
	fmt.Println(cli.ZRem("lang","javaScript","java").Val())//2

	fmt.Println(cli.ZRange("lang",0,-1).Val())	// [ruby php python go]
	// 升序:根据下标区间移除指定成员
	fmt.Println(cli.ZRemRangeByRank("lang",1,2).Val())		//2:表示移除了两个
	fmt.Println(cli.ZRangeWithScores("lang",0,-1).Val())	// [{50 ruby} {80 go}]
	// 升序:根据分数区间移除指定成员
	fmt.Println(cli.ZRemRangeByScore("lang","70","90").Val())	//1:表示移除了一个
	fmt.Println(cli.ZRangeWithScores("lang",0,-1).Val())	// [{50 ruby}]
}

func main() {
	rdb := GetRedisClient()
	defer rdb.Close()
	pong := rdb.Ping().Val()
	fmt.Printf("数据库连接状态:%v\n", pong) // 数据连接状态:PONG

	redisZsetTest(rdb)
}
 类似资料: