Before implementing the cache sorting function, you must first clarify the rationality of this function. Now that you can sort data in the database, why do you need to put the sorting function in the cache? The following two reasons are briefly summarized: first, sorting increases the load on the database and is difficult to support highly concurrent applications. Second, sorting in the cache will not encounter the problem of table locking. Redis just provides the sorting function, so that we can conveniently sort the cache.
In redis, the sort command is used to implement the sorting function. This command provides multiple parameters to sort lists, sets, and sorted sets. The sort command format is as follows:
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
The by parameter is used to specify the sorting field. The function is similar to the order by parameter in SQL. For lists and sets, sorting by their values alone is often meaningless. Take the set returned by the cache2hash function as an example (the set key is actually returned). The set stores a series of complete hash keys, which are sorted only by these keys, the result is simply arranged in numbers or dictionary order, and its usage is obviously not large. This is because the hash structure rather than the hash key is used to store row data. Assume that the set key is "resultset. hash: 123456 ", each hash key in the set corresponds to a hash structure with a field named" timestamp ". Now we want to sort all the hash keys in the set according to the timestamp field, run the following command:
SORT resultset.hash:123456 BY *->timestamp
From the above example, we can see that the real power of by is that it allows the sort command to sort according to the external field of a specified external key. Sort uses the set resultset. hash: Replace the first "*" after the by parameter for each value (that is, each hash key) in 123456, and obtain the value based on the field given after "->, finally, sort the hash key based on these field values.
The limit parameter is used to limit the number of elements returned after sorting. It is similar to the limit parameter in SQL. This parameter accepts two other parameters, namely offset and count. Limit offset count indicates that the first offset element is skipped and the Count element is returned continuously. It can be seen that the limit parameter can be used to implement the paging function.
The get parameter is used to return the specified field value. Take the resultset. Hash: 123456 as an example. After the by parameter is used to sort all hash keys in the set according to the timestamp field in the hash structure, the sort command returns all sorted Hash keys. If a request requires some field values instead of keys, you must use the get parameter so that the sort command returns the specified field value. In addition to the timestamp field, the hash structure corresponding to each hash key in the Set also contains a field named "ID, run the following command to enable sort to return the values of Timestamp and ID in the hash structure corresponding to each hash key sorted by timestamp:
SORT resultset.hash:123456 BY *->timestamp GET *->timestamp GET *->id
Sort replaces the first "*" after the get parameter with each value (that is, each hash key) in the resultset. Hash: 123456 set and uses it as the return value. It is worth noting that you can use get # To get the hash key itself in the set.
The ASC and desc parameters are used to specify the sorting order (ASC by default, from low to high), and the Alpha parameter is used to sort non-numeric elements alphabetically.
The store parameter is used to save the return value of the sort command, that is, the sorting result to a specified list. After the store parameter is added, the return value of the sort command changes to the number of sorting results.
The following code sorts the hash keys in the set by a hash field and saves the result to the list:
// This function sorts all hash keys in the Set Based on a field in the hash key corresponding to the hash key. // The sorting result is saved to a list structure, the list key should contain the result set identifier and sorting Field identifier, // such as "sorted: 123456: 1234" string sorthash (SQL: Connection * mysql_connection, rediscontext * redis_connection, const string & resultset_id, const string & sort_field, int offset, int count, int order, int TTL) {// only set string redis_row_set_key = "resultset that stores the hash key. hash: "+ resultset_id; redisreply * reply; // check Set whether reply = static_cast <redisreply *> (rediscommand (redis_connection, "exists % s", redis_row_set_key.c_str (); If (reply-> integer = 0) {freereplyobject (reply); throw runtime_error ("Failure-No resultsets");} else {freereplyobject (reply);} string field_md5 = MD5 (sort_field ); // use MD5 to exclude the influence caused by spaces in the sorting field // Save the sorting result to the list string redis_sorted_list_key = "sorted:" + resultset_id + ":" + field_md5; ST Ring by ("*->" + sort_field); // determine the sorting field string ord = (Order = 1 )? "ASC": "DESC"; // order = 1 is sorted in ascending order; otherwise, it is stringstream ofsstream, cntstream; ofsstream <OFFSET; cntstream <count; // execute the sorting command and save the sorting result to list reply = static_cast <redisreply *> (rediscommand (redis_connection, "Sort % s by % s limit % S % s get % s alpha store % s", redis_row_set_key.c_str (),. c_str (), ofsstream. STR (). c_str (), cntstream. STR (). c_str (), "#", redis_sorted_list_key.c_str (); freereplyobject (reply); stringstream ttlstream; ttlstream <TTL; // set the expiration time of the List reply = static_cast <redisreply *> (rediscommand (redis_connection, "expire % S % s", redis_sorted_list_key.c_str (), ttlstream. STR (). c_str (); freereplyobject (reply); Return redis_sorted_list_key; // return the list key, so that other functions can obtain the content in the list.
Obviously, sorting hash keys in the result set is more intuitive and convenient than sorting string keys. The sorting function allows you to conveniently query the sorted result set in redis. The Code is as follows:
// This function queries and sorts the corresponding result set in redis based on SQL statements and sorting parameters, and finally returns the hash key vector <string> getsortedcache (SQL:: Connection * mysql_connection, rediscontext * redis_connection, const string & SQL, const string & sort_field, int offset, int count, int order, int TTL) {vector <string> redis_row_key_vector; redisreply * reply; string resultset_id = MD5 (SQL); // result set identifier string field_md5 = MD5 (sort_field ); // sort Field identifier // try to get all hash keys in the list string redis_sorted_list_key = "sorted:" + resultset_id + ":" + field_md5; // try to get all hash keys in the list reply = static_cast <redisreply *> (rediscommand (redis_connection, "lrange % S % s", redis_sorted_list_key.c_str (), "0 ", "-1"); If (reply-> type = redis_reply_array) {// if the list does not exist, call the cache2hash function to pull data from MySQL to redis, then, call the sorthash function // sort the result set and save the sorted Hash key to list if (reply-> elements = 0) {freereplyobject (reply); SQL :: statement * stmt = mysql_connection-> createstatement (); SQL: resultset * resultset = stmt-> executequery (SQL); cache2hash (mysql_connection, redis_connection, resultset, resultset_id, TTL ); redis_sorted_list_key = sorthash (mysql_connection, redis_connection, resultset_id, sort_field, offset, Count, order, TTL ); // try again to get all hash keys in the list reply = static_cast <redisreply *> (rediscommand (redis_connection, "lrange % S % s", redis_sorted_list_key.c_str (), "0 ", "-1"); Delete resultset; Delete stmt;} // save all hash keys in the list to string redis_row_key_key; For (INT I = 0; I <reply-> elements; ++ I) {redis_row_key = reply-> element [I]-> STR; redis_row_key_vector.push_back (redis_row_key);} freereplyobject (reply );} else {freereplyobject (reply); throw runtime_error ("Failure-lrange error");} return redis_row_key_vector ;}
In this way, you can simply sort the result set in redis.
Redis (4) for beginners -- simple implementation of the redis cache sorting Function