github.com/therealbill/libredis@v0.0.0-20161227004305-7d50abda5ccf/client/sorted_sets.go (about) 1 package client 2 3 import ( 4 "errors" 5 "strconv" 6 ) 7 8 // ZAdd adds all the specified members with the specified scores to the sorted set stored at key. 9 // If a specified member is already a member of the sorted set, 10 // the score is updated and the element reinserted at the right position to ensure the correct ordering. 11 // If key does not exist, a new sorted set with the specified members as sole members is created, 12 // like if the sorted set was empty. 13 // If the key exists but does not hold a sorted set, an error is returned. 14 // 15 // Return value: 16 // The number of elements added to the sorted sets, 17 // not including elements already existing for which the score was updated. 18 func (r *Redis) ZAdd(key string, score float64, val string) (int64, error) { 19 rp, err := r.ExecuteCommand("ZADD", key, score, val) 20 if err != nil { 21 return 0, err 22 } 23 return rp.IntegerValue() 24 } 25 26 func (r *Redis) ZAddVariadic(key string, pairs map[string]float64) (int64, error) { 27 args := packArgs("ZADD", key) 28 for member, score := range pairs { 29 args = append(args, score, member) 30 } 31 rp, err := r.ExecuteCommand(args...) 32 if err != nil { 33 return 0, err 34 } 35 return rp.IntegerValue() 36 } 37 38 // ZCard returns the sorted set cardinality (number of elements) of the sorted set stored at key. 39 // Integer reply: the cardinality (number of elements) of the sorted set, or 0 if key does not exist. 40 func (r *Redis) ZCard(key string) (int64, error) { 41 rp, err := r.ExecuteCommand("ZCARD", key) 42 if err != nil { 43 return 0, err 44 } 45 return rp.IntegerValue() 46 } 47 48 // ZCount returns the number of elements in the sorted set at key with a score between min and max. 49 // The min and max arguments have the same semantic as described for ZRANGEBYSCORE. 50 // Integer reply: the number of elements in the specified score range. 51 func (r *Redis) ZCount(key, min, max string) (int64, error) { 52 rp, err := r.ExecuteCommand("ZCOUNT", key, min, max) 53 if err != nil { 54 return 0, err 55 } 56 return rp.IntegerValue() 57 } 58 59 // ZIncrBy increments the score of member in the sorted set stored at key by increment. 60 // If member does not exist in the sorted set, it is added with increment as its score 61 // (as if its previous score was 0.0). 62 // If key does not exist, a new sorted set with the specified member as its sole member is created. 63 // An error is returned when key exists but does not hold a sorted set. 64 // Bulk reply: the new score of member (a double precision floating point number), represented as string. 65 func (r *Redis) ZIncrBy(key string, increment float64, member string) (float64, error) { 66 rp, err := r.ExecuteCommand("ZINCRBY", key, increment, member) 67 if err != nil { 68 return 0.0, err 69 } 70 s, err := rp.StringValue() 71 if err != nil { 72 return 0.0, err 73 } 74 score, err := strconv.ParseFloat(s, 64) 75 if err != nil { 76 return 0.0, err 77 } 78 return score, nil 79 } 80 81 // ZInterStore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] 82 func (r *Redis) ZInterStore(destination string, keys []string, weights []int, aggregate string) (int64, error) { 83 args := packArgs("ZINTERSTORE", destination, len(keys), keys) 84 if weights != nil && len(weights) > 0 { 85 args = append(args, "WEIGHTS") 86 for _, w := range weights { 87 args = append(args, w) 88 } 89 } 90 if aggregate != "" { 91 args = append(args, "AGGREGATE", aggregate) 92 } 93 rp, err := r.ExecuteCommand(args...) 94 if err != nil { 95 return 0, err 96 } 97 return rp.IntegerValue() 98 } 99 100 // ZLexCount returns the number of elements in the sorted set at key 101 // with a value between min and max in order to force lexicographical ordering. 102 func (r *Redis) ZLexCount(key, min, max string) (int64, error) { 103 rp, err := r.ExecuteCommand("ZLEXCOUNT", key, min, max) 104 if err != nil { 105 return 0, err 106 } 107 return rp.IntegerValue() 108 } 109 110 // ZRange returns the specified range of elements in the sorted set stored at key. 111 // The elements are considered to be ordered from the lowest to the highest score. 112 // Lexicographical order is used for elements with equal score. 113 // Multi-bulk reply: list of elements in the specified range.(optionally with their scores). 114 // It is possible to pass the WITHSCORES option in order to return the scores of the elements 115 // together with the elements. 116 // The returned list will contain value1,score1,...,valueN,scoreN instead of value1,...,valueN. 117 func (r *Redis) ZRange(key string, start, stop int, withscores bool) ([]string, error) { 118 args := []interface{}{"ZRANGE", key, start, stop} 119 if withscores { 120 args = append(args, "WITHSCORES") 121 } 122 rp, err := r.ExecuteCommand(args...) 123 if err != nil { 124 return nil, err 125 } 126 return rp.ListValue() 127 } 128 129 // ZRangeByLex returns all the elements in the sorted set at key with a value between min and max 130 // in order to force lexicographical ordering. 131 func (r *Redis) ZRangeByLex(key, min, max string, limit bool, offset, count int) ([]string, error) { 132 args := packArgs("ZRANGEBYLEX", key, min, max) 133 if limit { 134 args = append(args, "LIMIT", offset, count) 135 } 136 rp, err := r.ExecuteCommand(args...) 137 if err != nil { 138 return nil, err 139 } 140 return rp.ListValue() 141 } 142 143 // ZRangeByScore key min max [WITHSCORES] [LIMIT offset count] 144 func (r *Redis) ZRangeByScore(key, min, max string, withscores, limit bool, offset, count int) ([]string, error) { 145 args := packArgs("ZRANGEBYSCORE", key, min, max) 146 if withscores { 147 args = append(args, "WITHSCORES") 148 } 149 if limit { 150 args = append(args, "LIMIT", offset, count) 151 } 152 rp, err := r.ExecuteCommand(args...) 153 if err != nil { 154 return nil, err 155 } 156 return rp.ListValue() 157 } 158 159 // ZRank returns the rank of member in the sorted set stored at key, 160 // with the scores ordered from low to high. 161 // The rank (or index) is 0-based, which means that the member with the lowest score has rank 0. 162 // 163 // If member exists in the sorted set, Integer reply: the rank of member. 164 // If member does not exist in the sorted set or key does not exist, Bulk reply: nil. 165 // -1 represent the nil bulk rely. 166 func (r *Redis) ZRank(key, member string) (int64, error) { 167 rp, err := r.ExecuteCommand("ZRANK", key, member) 168 if err != nil { 169 return -1, err 170 } 171 if rp.Type == ErrorReply { 172 return -1, errors.New(rp.Error) 173 } 174 if rp.Type == IntegerReply { 175 return rp.Integer, nil 176 } 177 if rp.Type == BulkReply { 178 return -1, nil 179 } 180 return -1, errors.New("ZRANK reply protocol error") 181 } 182 183 // ZRem removes the specified members from the sorted set stored at key. Non existing members are ignored. 184 // An error is returned when key exists and does not hold a sorted set. 185 // Integer reply, specifically: 186 // The number of members removed from the sorted set, not including non existing members. 187 func (r *Redis) ZRem(key string, members ...string) (int64, error) { 188 args := packArgs("ZREM", key, members) 189 rp, err := r.ExecuteCommand(args...) 190 if err != nil { 191 return 0, err 192 } 193 return rp.IntegerValue() 194 } 195 196 // ZRemRangeByLex removes all elements in the sorted set stored at key 197 // between the lexicographical range specified by min and max. 198 func (r *Redis) ZRemRangeByLex(key, min, max string) (int64, error) { 199 rp, err := r.ExecuteCommand("ZREMRANGEBYLEX", key, min, max) 200 if err != nil { 201 return 0, err 202 } 203 return rp.IntegerValue() 204 } 205 206 // ZRemRangeByRank removes all elements in the sorted set stored at key with rank between start and stop. 207 // Both start and stop are 0 -based indexes with 0 being the element with the lowest score. 208 // These indexes can be negative numbers, where they indicate offsets starting at the element with the highest score. 209 // For example: -1 is the element with the highest score, -2 the element with the second highest score and so forth. 210 // Integer reply: the number of elements removed. 211 func (r *Redis) ZRemRangeByRank(key string, start, stop int) (int64, error) { 212 rp, err := r.ExecuteCommand("ZREMRANGEBYRANK", key, start, stop) 213 if err != nil { 214 return 0, err 215 } 216 return rp.IntegerValue() 217 } 218 219 // ZRemRangeByScore removes all elements in the sorted set stored at key with a score between min and max (inclusive). 220 // Integer reply: the number of elements removed. 221 func (r *Redis) ZRemRangeByScore(key, min, max string) (int64, error) { 222 rp, err := r.ExecuteCommand("ZREMRANGEBYSCORE", key, min, max) 223 if err != nil { 224 return 0, err 225 } 226 return rp.IntegerValue() 227 } 228 229 // ZRevRange returns the specified range of elements in the sorted set stored at key. 230 // The elements are considered to be ordered from the highest to the lowest score. 231 // Descending lexicographical order is used for elements with equal score. 232 // Multi-bulk reply: list of elements in the specified range (optionally with their scores). 233 func (r *Redis) ZRevRange(key string, start, stop int, withscores bool) ([]string, error) { 234 args := []interface{}{"ZREVRANGE", key, start, stop} 235 if withscores { 236 args = append(args, "WITHSCORES") 237 } 238 rp, err := r.ExecuteCommand(args...) 239 if err != nil { 240 return nil, err 241 } 242 return rp.ListValue() 243 } 244 245 // ZRevRangeByScore key max min [WITHSCORES] [LIMIT offset count] 246 func (r *Redis) ZRevRangeByScore(key, max, min string, withscores, limit bool, offset, count int) ([]string, error) { 247 args := packArgs("ZREVRANGEBYSCORE", key, max, min) 248 if withscores { 249 args = append(args, "WITHSCORES") 250 } 251 if limit { 252 args = append(args, "LIMIT", offset, count) 253 } 254 rp, err := r.ExecuteCommand(args...) 255 if err != nil { 256 return nil, err 257 } 258 return rp.ListValue() 259 } 260 261 // ZRevRank returns the rank of member in the sorted set stored at key, 262 // with the scores ordered from high to low. The rank (or index) is 0-based, 263 // which means that the member with the highest score has rank 0. 264 func (r *Redis) ZRevRank(key, member string) (int64, error) { 265 rp, err := r.ExecuteCommand("ZREVRANK", key, member) 266 if err != nil { 267 return -1, err 268 } 269 if rp.Type == ErrorReply { 270 return -1, errors.New(rp.Error) 271 } 272 if rp.Type == IntegerReply { 273 return rp.Integer, nil 274 } 275 if rp.Type == BulkReply { 276 return -1, nil 277 } 278 return -1, errors.New("ZREVRANK reply protocol error") 279 } 280 281 // ZScore returns the score of member in the sorted set at key. 282 // If member does not exist in the sorted set, or key does not exist, nil is returned. 283 // Bulk reply: the score of member (a double precision floating point number), represented as string. 284 func (r *Redis) ZScore(key, member string) ([]byte, error) { 285 rp, err := r.ExecuteCommand("ZSCORE", key, member) 286 if err != nil { 287 return nil, err 288 } 289 return rp.BytesValue() 290 } 291 292 // ZUnionStore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] 293 func (r *Redis) ZUnionStore(destination string, keys []string, weights []int, aggregate string) (int64, error) { 294 args := packArgs("ZUNIONSTORE", destination, len(keys), keys) 295 if weights != nil && len(weights) > 0 { 296 args = append(args, "WEIGHTS") 297 for _, w := range weights { 298 args = append(args, w) 299 } 300 } 301 if aggregate != "" { 302 args = append(args, "AGGREGATE", aggregate) 303 } 304 rp, err := r.ExecuteCommand(args...) 305 if err != nil { 306 return 0, err 307 } 308 return rp.IntegerValue() 309 } 310 311 // ZScan key cursor [MATCH pattern] [COUNT count] 312 func (r *Redis) ZScan(key string, cursor uint64, pattern string, count int) (uint64, []string, error) { 313 args := packArgs("ZSCAN", key, cursor) 314 if pattern != "" { 315 args = append(args, "MATCH", pattern) 316 } 317 if count > 0 { 318 args = append(args, "COUNT", count) 319 } 320 rp, err := r.ExecuteCommand(args...) 321 if err != nil { 322 return 0, nil, err 323 } 324 first, err := rp.Multi[0].StringValue() 325 if err != nil { 326 return 0, nil, err 327 } 328 next, err := strconv.ParseUint(first, 10, 64) 329 if err != nil { 330 return 0, nil, err 331 } 332 list, err := rp.Multi[1].ListValue() 333 return next, list, err 334 }