Skip to content

Commit 6ecbcf6

Browse files
Add ZRANK, ZREVRANK WITHSCORE (#2531)
* feat: adding zrankwithscore and zrevrankwithscore commands : redis 7.2 * fix: test for non-existing members * fix: Error check * fix: string to float * add ZRankWithScore API for Cmdable interface Signed-off-by: monkey92t <[email protected]> * add notes Signed-off-by: monkey92t <[email protected]> --------- Signed-off-by: monkey92t <[email protected]> Co-authored-by: Anuragkillswitch <[email protected]> Co-authored-by: monkey92t <[email protected]>
1 parent 38ca7c1 commit 6ecbcf6

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

command.go

+60
Original file line numberDiff line numberDiff line change
@@ -4724,3 +4724,63 @@ func (cmd *ClusterShardsCmd) readReply(rd *proto.Reader) error {
47244724

47254725
return nil
47264726
}
4727+
4728+
// -----------------------------------------
4729+
4730+
type RankScore struct {
4731+
Rank int64
4732+
Score float64
4733+
}
4734+
4735+
type RankWithScoreCmd struct {
4736+
baseCmd
4737+
4738+
val RankScore
4739+
}
4740+
4741+
var _ Cmder = (*RankWithScoreCmd)(nil)
4742+
4743+
func NewRankWithScoreCmd(ctx context.Context, args ...interface{}) *RankWithScoreCmd {
4744+
return &RankWithScoreCmd{
4745+
baseCmd: baseCmd{
4746+
ctx: ctx,
4747+
args: args,
4748+
},
4749+
}
4750+
}
4751+
4752+
func (cmd *RankWithScoreCmd) SetVal(val RankScore) {
4753+
cmd.val = val
4754+
}
4755+
4756+
func (cmd *RankWithScoreCmd) Val() RankScore {
4757+
return cmd.val
4758+
}
4759+
4760+
func (cmd *RankWithScoreCmd) Result() (RankScore, error) {
4761+
return cmd.val, cmd.err
4762+
}
4763+
4764+
func (cmd *RankWithScoreCmd) String() string {
4765+
return cmdString(cmd, cmd.val)
4766+
}
4767+
4768+
func (cmd *RankWithScoreCmd) readReply(rd *proto.Reader) error {
4769+
if err := rd.ReadFixedArrayLen(2); err != nil {
4770+
return err
4771+
}
4772+
4773+
rank, err := rd.ReadInt()
4774+
if err != nil {
4775+
return err
4776+
}
4777+
4778+
score, err := rd.ReadFloat()
4779+
if err != nil {
4780+
return err
4781+
}
4782+
4783+
cmd.val = RankScore{Rank: rank, Score: score}
4784+
4785+
return nil
4786+
}

commands.go

+18
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ type Cmdable interface {
373373
ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd
374374
ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd
375375
ZRank(ctx context.Context, key, member string) *IntCmd
376+
ZRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd
376377
ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd
377378
ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd
378379
ZRemRangeByScore(ctx context.Context, key, min, max string) *IntCmd
@@ -383,6 +384,7 @@ type Cmdable interface {
383384
ZRevRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd
384385
ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd
385386
ZRevRank(ctx context.Context, key, member string) *IntCmd
387+
ZRevRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd
386388
ZScore(ctx context.Context, key, member string) *FloatCmd
387389
ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd
388390
ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd
@@ -2884,6 +2886,14 @@ func (c cmdable) ZRank(ctx context.Context, key, member string) *IntCmd {
28842886
return cmd
28852887
}
28862888

2889+
// ZRankWithScore according to the Redis documentation, if member does not exist
2890+
// in the sorted set or key does not exist, it will return a redis.Nil error.
2891+
func (c cmdable) ZRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd {
2892+
cmd := NewRankWithScoreCmd(ctx, "zrank", key, member, "withscore")
2893+
_ = c(ctx, cmd)
2894+
return cmd
2895+
}
2896+
28872897
func (c cmdable) ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd {
28882898
args := make([]interface{}, 2, 2+len(members))
28892899
args[0] = "zrem"
@@ -2924,6 +2934,8 @@ func (c cmdable) ZRevRange(ctx context.Context, key string, start, stop int64) *
29242934
return cmd
29252935
}
29262936

2937+
// ZRevRangeWithScores according to the Redis documentation, if member does not exist
2938+
// in the sorted set or key does not exist, it will return a redis.Nil error.
29272939
func (c cmdable) ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd {
29282940
cmd := NewZSliceCmd(ctx, "zrevrange", key, start, stop, "withscores")
29292941
_ = c(ctx, cmd)
@@ -2974,6 +2986,12 @@ func (c cmdable) ZRevRank(ctx context.Context, key, member string) *IntCmd {
29742986
return cmd
29752987
}
29762988

2989+
func (c cmdable) ZRevRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd {
2990+
cmd := NewRankWithScoreCmd(ctx, "zrevrank", key, member, "withscore")
2991+
_ = c(ctx, cmd)
2992+
return cmd
2993+
}
2994+
29772995
func (c cmdable) ZScore(ctx context.Context, key, member string) *FloatCmd {
29782996
cmd := NewFloatCmd(ctx, "zscore", key, member)
29792997
_ = c(ctx, cmd)

commands_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -4737,6 +4737,31 @@ var _ = Describe("Commands", func() {
47374737
Expect(zRank.Val()).To(Equal(int64(0)))
47384738
})
47394739

4740+
It("should ZRankWithScore", func() {
4741+
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
4742+
Expect(err).NotTo(HaveOccurred())
4743+
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
4744+
Expect(err).NotTo(HaveOccurred())
4745+
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
4746+
Expect(err).NotTo(HaveOccurred())
4747+
4748+
zRankWithScore := client.ZRankWithScore(ctx, "zset", "one")
4749+
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
4750+
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 1}))
4751+
4752+
zRankWithScore = client.ZRankWithScore(ctx, "zset", "two")
4753+
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
4754+
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
4755+
4756+
zRankWithScore = client.ZRankWithScore(ctx, "zset", "three")
4757+
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
4758+
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 3}))
4759+
4760+
zRankWithScore = client.ZRankWithScore(ctx, "zset", "four")
4761+
Expect(zRankWithScore.Err()).To(HaveOccurred())
4762+
Expect(zRankWithScore.Err()).To(Equal(redis.Nil))
4763+
})
4764+
47404765
It("should ZRem", func() {
47414766
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
47424767
Expect(err).NotTo(HaveOccurred())
@@ -5008,6 +5033,31 @@ var _ = Describe("Commands", func() {
50085033
Expect(zRevRank.Val()).To(Equal(int64(0)))
50095034
})
50105035

5036+
It("should ZRevRankWithScore", func() {
5037+
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5038+
Expect(err).NotTo(HaveOccurred())
5039+
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5040+
Expect(err).NotTo(HaveOccurred())
5041+
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5042+
Expect(err).NotTo(HaveOccurred())
5043+
5044+
zRevRankWithScore := client.ZRevRankWithScore(ctx, "zset", "one")
5045+
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5046+
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 1}))
5047+
5048+
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "two")
5049+
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5050+
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
5051+
5052+
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "three")
5053+
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5054+
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 3}))
5055+
5056+
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "four")
5057+
Expect(zRevRankWithScore.Err()).To(HaveOccurred())
5058+
Expect(zRevRankWithScore.Err()).To(Equal(redis.Nil))
5059+
})
5060+
50115061
It("should ZScore", func() {
50125062
zAdd := client.ZAdd(ctx, "zset", redis.Z{Score: 1.001, Member: "one"})
50135063
Expect(zAdd.Err()).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)