Reputation: 659
I have a sorted set in Redis with timestamp and different type of relationships to the set is stored together.
Example dataset is explained below:
zadd s1 10 rel1:val1
zadd s1 15 rel1:val2
zadd s1 12 rel1:val3
zadd s1 10 rel2:v1
zadd s1 12 rel2:v2
zadd s1 5 rel1:v3
What I'm looking for top element of rel1 or rel2 from the set, if I tried to store them separately I will end with many keys, which I want to avoid.
I tried ZSCAN and the results are in asc order by score like below
localhost:6379> zscan s1 0 match "rel1*" count 10
1) "0"
2) 1) "rel1:v3"
2) "5"
3) "rel1:val1"
4) "10"
5) "rel1:val3"
6) "12"
7) "rel1:val2"
8) "15"
And if I score the timestamp in -ive I get the results as expected top element
localhost:6379> zadd s1 -10 rel1:val1
(integer) 0
localhost:6379> zadd s1 -20 rel1:val2
(integer) 0
localhost:6379> zadd s1 -30 rel1:val3
(integer) 0
localhost:6379> zscan s1 0 match "rel1*" count 10
1) "0"
2) 1) "rel1:val3"
2) "-30"
3) "rel1:val2"
4) "-20"
5) "rel1:val1"
6) "-10"
7) "rel1:v3"
8) "5"
My question can I relay on this results and believe the results are always in asc order with ZSCAN.
I can't use ZREVRANGE or ZRANGE commands as I have to get top n items with MATCHING the members.
Upvotes: 1
Views: 3573
Reputation: 1
If you use small sample data like the given one, you might probably get the correctly ordered results. But don't trust it.
Just as @for_stack said, ZSCAN doesn't keep the order of results. You could generate a large number of samples to test it, then you will find. You have to switch to ZRANGE, ZREVRANGE or other ways.
Upvotes: 0
Reputation: 22906
NO. You cannot rely on it. The order is undefined.
As we known, ZSET is implemented with a dict/hash, and a skiplist. ZSCAN command scans the dict, not the skiplist. Since dict is unordered, the order of scan result is undefined.
Upvotes: 2