ZRANGEBYLEX(3valkey)

πŸ“¦
version 9.0.6 Β· 2 versions
, in fedora 44

πŸ’… ZRANGEBYLEX β€” the valkey command manual, but make it cute

okay bestie, welcome to ZRANGEBYLEX(3valkey), the valkey command manual page where we get lexicographical πŸ”₯ no cap.


✨ NAME ✨

zrangebylex β€” returns members in a sorted set within a lexicographical range. it's giving dictionary vibes only. πŸ’–


🌸 SYNOPSIS 🌸

ZRANGEBYLEX key min max [LIMIT offset count]

πŸ¦‹ DESCRIPTION πŸ¦‹

so here's the tea, bestie: when all the elements in a sorted set are inserted with the same score, to force lexicographical ordering, this command returns all the elements in the sorted set at key with a value between min and max. periodt. ✨

but β€” and this is important β€” if the elements in the sorted set have different scores, the returned elements are unspecified. not undefined, not "eh probably fine", just unspecified. lowkey cursed. πŸ’€

the elements are considered to be ordered from lower to higher strings, compared byte-by-byte using the memcmp() C function. and if the common part is identical, longer strings are considered greater than shorter strings. longer = bigger energy, iykyk. πŸ‘‘

the optional LIMIT argument can be used to only get a range of the matching elements β€” literally the same idea as SELECT LIMIT offset, count in SQL. a negative count returns all elements from the offset. but keep in mind, bestie: if offset is large, the sorted set needs to be traversed for offset elements before getting to the elements to return, which can add up to O(N) time complexity. so maybe don't do that. 🫢

πŸŽ€ How to specify intervals πŸŽ€

valid start and stop must start with ( or [, to specify if the range item is respectively exclusive or inclusive. that's the whole rule, no notes. πŸ’…

the special values + or - for start and stop have the special meaning of positively infinite and negatively infinite strings. so for instance the command

ZRANGEBYLEX myzset - +

is guaranteed to return all the elements in the sorted set, if all the elements have the same score. iconic behaviour honestly. ✨

🌈 Details on strings comparison 🌈

strings are compared as binary array of bytes. because of how the ASCII character set is specified, this usually also has the effect of comparing normal ASCII characters in an obvious dictionary way. however, this is not true if non plain ASCII strings are used (for example utf8 strings). so watch out for that one. 😭

but!! the user can apply a transformation to the encoded string so that the first part of the element inserted in the sorted set will compare as the user requires for the specific application. for example, if I want to add strings that will be compared in a case-insensitive way, but I still want to retrieve the real case when querying, I can add strings in the following way:

ZADD autocomplete 0 foo:Foo 0 bar:BAR 0 zap:zap

because of the first normalized part in every element (before the colon character), we are forcing a given comparison. however, after the range is queried using ZRANGEBYLEX, the application can display to the user the second part of the string, after the colon. the first part does the sorting, the second part does the serving. main character energy fr fr. πŸ’–

the binary nature of the comparison allows you to use sorted sets as a general purpose index. for example the first part of the element can be a 64 bit big endian number: since big endian numbers have the most significant bytes in the initial positions, the binary comparison will match the numerical comparison of the numbers. this can be used in order to implement range queries on 64 bit values. as in the example below, after the first 8 bytes we can store the value of the element we are actually indexing. slay. πŸ”₯

🧚 Alternative 🧚

ZRANGE with the BYLEX argument. same vibe, different door. πŸšͺ


πŸ’œ REPLY πŸ’œ

valkey-protocol(7) Array reply: a list of elements in the specified score range.


⭐ COMPLEXITY ⭐

O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. if M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)). math ate, honestly. ✨


πŸ‘‘ ACL CATEGORIES πŸ‘‘

@read @slow @sortedset


πŸ“ HISTORY πŸ“

  • Available since: 2.8.9

an elder. a legend. we stan. 🫢


🌸 EXAMPLES 🌸

127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
127.0.0.1:6379> ZRANGEBYLEX myzset - [c
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> ZRANGEBYLEX myzset - (c
1) "a"
2) "b"
127.0.0.1:6379> ZRANGEBYLEX myzset [aaa (g
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"

look at her go. πŸ˜­πŸ’–


πŸŽ€ SEE ALSO πŸŽ€

bzmpop(3valkey), bzpopmax(3valkey), bzpopmin(3valkey), zadd(3valkey), zcard(3valkey), zcount(3valkey), zdiff(3valkey), zdiffstore(3valkey), zincrby(3valkey), zinter(3valkey), zintercard(3valkey), zinterstore(3valkey), zlexcount(3valkey), zmpop(3valkey), zmscore(3valkey), zpopmax(3valkey), zpopmin(3valkey), zrandmember(3valkey), zrange(3valkey), zrangebyscore(3valkey), zrangestore(3valkey), zrank(3valkey), zrem(3valkey), zremrangebylex(3valkey), zremrangebyrank(3valkey), zremrangebyscore(3valkey), zrevrange(3valkey), zrevrangebylex(3valkey), zrevrangebyscore(3valkey), zrevrank(3valkey), zscan(3valkey), zscore(3valkey), zunion(3valkey), zunionstore(3valkey)


and that's the whole page, bestie! go forth and lexicographically range. 🌈

this was 9.0.0, dated 2025-10-21, and it's been ZRANGEBYLEX(3valkey) the entire time. bye bestie, love u, mwah πŸ’…πŸ’–

πŸ“¦ where this page comes from