go-redis icon indicating copy to clipboard operation
go-redis copied to clipboard

Does go-redis support to get original result format? Eg, zrangewithscores in redis return a one-dimensional array, but in go-redis I get redis.Z slice, I want to get original result

Open TonyStarkIron opened this issue 1 year ago • 2 comments

Discussed in https://github.com/redis/go-redis/discussions/2837

Originally posted by TonyStarkIron December 18, 2023 My app is a redis proxy to receive redis command and return results, however, go-redis returns redis.Z when command is ZRangeWithScores and other clients can't parse. I want to this result format, image but I get this in go-redis: image

TonyStarkIron avatar Dec 18 '23 06:12 TonyStarkIron

A scenarios is my app receives redis command from Jedis , then uses go-redis execute command and returns resp result to Jedis . but as for ZRangeWithScores, go-redis gets redis.Z slice, which leads to Jedis Unknown Reply exception.

TonyStarkIron avatar Dec 18 '23 06:12 TonyStarkIron

@TonyStarkIron Essentially we read the reply from Redis and parse it to this more Go-friendly format

func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error { // nolint:dupl
	n, err := rd.ReadArrayLen()
	if err != nil {
		return err
	}

	// If the n is 0, can't continue reading.
	if n == 0 {
		cmd.val = make([]Z, 0)
		return nil
	}

	typ, err := rd.PeekReplyType()
	if err != nil {
		return err
	}
	array := typ == proto.RespArray

	if array {
		cmd.val = make([]Z, n)
	} else {
		cmd.val = make([]Z, n/2)
	}

	for i := 0; i < len(cmd.val); i++ {
		if array {
			if err = rd.ReadFixedArrayLen(2); err != nil {
				return err
			}
		}

		if cmd.val[i].Member, err = rd.ReadString(); err != nil {
			return err
		}

		if cmd.val[i].Score, err = rd.ReadFloat(); err != nil {
			return err
		}
	}

	return nil
}

Any reason you're not trying some post processing to convert the parsed redis.Z slice back into the original one-dimensional array format?

SoulPancake avatar Dec 19 '23 14:12 SoulPancake