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  }