Sort hash field in spring redis

This post is just a copy of one of my answer at stackoverflow.

The code is at the last of the post, if you are familiar with the principle of multi hset keys sort in redis, skip the following content and directly read the code.

Redis Sort is aimed to sort fields inside List/Set/Zset, but this method can be used to sort multi keys base on specified metric we want. We can use “sort” to sort multi hset keys by specified field, but there is limitation about the pattern of hset keys.
For example, if the pattern of hset keys is “hash{i}”(i is an integer), under this condition we can sort it.

127.0.0.1:6379> keys hash*
1) "hash3"
2) "hash2"
3) "hash1"

Take a look at the content of hash1:

127.0.0.1:6379> hgetall hash1
1) "id"
2) "24"
3) "name"
4) "kobe"

Every hash key contains two fields : “id”, “name”. If we want to sort these hset keys by its id. What should we do ?

First, add a set key named “myset”. “myset” is a set key which contains members {“1”, “2”, “3”}.

127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"

Then run the following command:

127.0.0.1:6379> SORT myset BY hash*->id GET hash*->id GET hash*->name
1) "3"
2) "wade"
3) "24"
4) "kobe"
5) "30"
6) "curry"

Eureka, sort hash{1-3} by its id.
Here is the code of using Spring Redis to do the job:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public static String getRandomStr() {
return String.valueOf(new Random().nextInt(100));
}
public static void redisTemplateSort(RedisTemplate redisTemplate) {
String sortKey = "sortKey";
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
redisTemplate.delete(sortKey);
if (!redisTemplate.hasKey(sortKey)) {
for (int i = 0; i < 10; i++) {
redisTemplate.boundSetOps(sortKey).add(String.valueOf(i));
String hashKey = "hash" + i,
strId = String.valueOf(i),
strName = getRandomStr(),
strSite = getRandomStr();
redisTemplate.boundHashOps(hashKey).put("_id", strId);
redisTemplate.boundHashOps(hashKey).put("Name", strName);
redisTemplate.boundHashOps(hashKey).put("Site", strSite);
System.out.printf("%s : {\"_id\": %s, \"Name\": %s, \"Site\", %s}\n",
hashKey, strId, strName, strSite);
}
}
SortQuery<String> sortQuery = SortQueryBuilder.sort(sortKey).by("hash*->Name")
.get("hash*->_id").get("hash*->Name").get("hash*->Site").build();
List<String> sortRslt = redisTemplate.sort(sortQuery);
for (int i = 0; i < sortRslt.size(); ) {
System.out.printf("{\"_id\": %s, \"Name\": %s, \"Site\", %s}\n", sortRslt.get(i+2), sortRslt.get(i+1), sortRslt.get(i));
i += 3;
}
}

Result of running redisTemplateSort(redisTemplate)(as sort by name in the code) :

hash0 : {"_id": 0, "Name": 59, "Site", 60}
hash1 : {"_id": 1, "Name": 37, "Site", 57}
hash2 : {"_id": 2, "Name": 6, "Site", 40}
hash3 : {"_id": 3, "Name": 91, "Site", 58}
hash4 : {"_id": 4, "Name": 39, "Site", 32}
hash5 : {"_id": 5, "Name": 27, "Site", 82}
hash6 : {"_id": 6, "Name": 43, "Site", 10}
hash7 : {"_id": 7, "Name": 17, "Site", 55}
hash8 : {"_id": 8, "Name": 14, "Site", 91}
hash9 : {"_id": 9, "Name": 39, "Site", 91}
{"_id": 40, "Name": 6, "Site", 2}
{"_id": 91, "Name": 14, "Site", 8}
{"_id": 55, "Name": 17, "Site", 7}
{"_id": 82, "Name": 27, "Site", 5}
{"_id": 57, "Name": 37, "Site", 1}
{"_id": 32, "Name": 39, "Site", 4}
{"_id": 91, "Name": 39, "Site", 9}
{"_id": 10, "Name": 43, "Site", 6}
{"_id": 60, "Name": 59, "Site", 0}
{"_id": 58, "Name": 91, "Site", 3}


profile for sel-fish at Stack Overflow, Q&A for professional and enthusiast programmers