redis之sort命令

來源:互聯網
上載者:User

SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]

返回或儲存給定列表、集合、有序集合 key 中經過排序的元素。

排序預設以數字作為對象,值被解釋為雙精確度浮點數,然後進行比較。

一、一般sort用法

最簡單的 SORT 使用方法是 SORT key 和 SORT key DESC :

      SORT key 返回索引值從小到大排序的結果。

     SORT key DESC 返回索引值從大到小排序的結果。

假設 today_cost 列表儲存了今日的開銷金額, 那麼可以用 SORT 命令對它進行排序:

# 開銷金額列表redis> LPUSH today_cost 30 1.5 10 8(integer) 4# 排序redis> SORT today_cost1) "1.5"2) "8"3) "10"4) "30"# 逆序排序redis 127.0.0.1:6379> SORT today_cost DESC1) "30"2) "10"3) "8"4) "1.5"

二、使用 ALPHA 修飾符對字串進行排序

因為 SORT 命令預設排序對象為數字, 當需要對字串進行排序時, 需要顯式地在 SORT 命令之後添加 ALPHA 修飾符:

# 網址redis> LPUSH website "www.reddit.com"(integer) 1redis> LPUSH website "www.slashdot.com"(integer) 2redis> LPUSH website "www.infoq.com"(integer) 3# 預設(按數字)排序redis> SORT website1) "www.infoq.com"2) "www.slashdot.com"3) "www.reddit.com"# 按字元排序redis> SORT website ALPHA1) "www.infoq.com"2) "www.reddit.com"3) "www.slashdot.com"

如果系統正確地設定了 LC_COLLATE 環境變數的話,Redis能識別 UTF-8 編碼。 三、使用 LIMIT 修飾符限制返回結果

排序之後返回元素的數量可以通過 LIMIT 修飾符進行限制, 修飾符接受 offset 和 count 兩個參數:

    offset 指定要跳過的元素數量。

    count 指定跳過 offset 個指定的元素之後,要返回多少個對象。

以下例子返回排序結果的前 5 個對象( offset 為 0 表示沒有元素被跳過)。

# 添加測試資料,列表值為 1 指 10redis 127.0.0.1:6379> RPUSH rank 1 3 5 7 9(integer) 5redis 127.0.0.1:6379> RPUSH rank 2 4 6 8 10(integer) 10# 返回列表中最小的 5 個值redis 127.0.0.1:6379> SORT rank LIMIT 0 51) "1"2) "2"3) "3"4) "4"5) "5"

可以組合使用多個修飾符。以下例子返回從大到小排序的前 5 個對象。

redis 127.0.0.1:6379> SORT rank LIMIT 0 5 DESC1) "10"2) "9"3) "8"4) "7"5) "6"
四、使用外部 key 進行排序

可以使用外部 key 的資料作為權重,代替預設的直接對比索引值的方式來進行排序。

假設現在有使用者資料如下:

uid user_name_{uid} user_level_{uid}

1 admin 9999

2 jack 10

3 peter 25

4 mary 70

以下代碼將資料輸入到 Redis 中:

# adminredis 127.0.0.1:6379> LPUSH uid 1(integer) 1redis 127.0.0.1:6379> SET user_name_1 adminOKredis 127.0.0.1:6379> SET user_level_1 9999OK# jackredis 127.0.0.1:6379> LPUSH uid 2(integer) 2redis 127.0.0.1:6379> SET user_name_2 jackOKredis 127.0.0.1:6379> SET user_level_2 10OK# peterredis 127.0.0.1:6379> LPUSH uid 3(integer) 3redis 127.0.0.1:6379> SET user_name_3 peterOKredis 127.0.0.1:6379> SET user_level_3 25OK# maryredis 127.0.0.1:6379> LPUSH uid 4(integer) 4redis 127.0.0.1:6379> SET user_name_4 maryOKredis 127.0.0.1:6379> SET user_level_4 70OK

BY 選項

預設情況下, SORT uid 直接按 uid 中的值排序:

redis 127.0.0.1:6379> SORT uid1) "1"      # admin2) "2"      # jack3) "3"      # peter4) "4"      # mary

通過使用 BY 選項,可以讓 uid 按其他鍵的元素來排序。

比如說, 以下代碼讓 uid 鍵按照 user_level_{uid} 的大小來排序:

redis 127.0.0.1:6379> SORT uid BY user_level_*1) "2"      # jack , level = 102) "3"      # peter, level = 253) "4"      # mary, level = 704) "1"      # admin, level = 9999

user_level_* 是一個預留位置, 它先取出 uid 中的值, 然後再用這個值來尋找相應的鍵。

比如在對 uid 列表進行排序時, 程式就會先取出 uid 的值 1 、 2 、 3 、 4 , 然後使用 user_level_1 、 user_level_2 、 user_level_3 和 user_level_4 的值作為排序 uid 的權重。

GET 選項

使用 GET 選項, 可以根據排序的結果來取出相應的索引值。

比如說, 以下代碼先排序 uid , 再取出鍵 user_name_{uid} 的值:

redis 127.0.0.1:6379> SORT uid GET user_name_*1) "admin"2) "jack"3) "peter"4) "mary"

組合使用 BY 和 GET

通過組合使用 BY 和 GET , 可以讓排序結果以更直觀的方式顯示出來。

比如說, 以下代碼先按 user_level_{uid} 來排序 uid 列表, 再取出相應的 user_name_{uid} 的值:

redis 127.0.0.1:6379> SORT uid BY user_level_* GET user_name_*1) "jack"       # level = 102) "peter"      # level = 253) "mary"       # level = 704) "admin"      # level = 9999

現在的排序結果要比只使用 SORT uid BY user_level_* 要直觀得多。

擷取多個外部鍵

可以同時使用多個 GET 選項, 擷取多個外部鍵的值。

以下代碼就按 uid 分別擷取 user_level_{uid} 和 user_name_{uid} :

redis 127.0.0.1:6379> SORT uid GET user_level_* GET user_name_*1) "9999"       # level2) "admin"      # name3) "10"4) "jack"5) "25"6) "peter"7) "70"8) "mary"

GET 有一個額外的參數規則,那就是 —— 可以用 # 擷取被排序鍵的值。

以下代碼就將 uid 的值、及其相應的 user_level_* 和 user_name_* 都返回為結果:

redis 127.0.0.1:6379> SORT uid GET # GET user_level_* GET user_name_*1) "1"          # uid2) "9999"       # level3) "admin"      # name4) "2"5) "10"6) "jack"7) "3"8) "25"9) "peter"10) "4"11) "70"12) "mary"

擷取外部鍵,但不進行排序

通過將一個不存在的鍵作為參數傳給 BY 選項, 可以讓 SORT 跳過排序操作, 直接返回結果:

redis 127.0.0.1:6379> SORT uid BY not-exists-key1) "4"2) "3"3) "2"4) "1"

這種用法在單獨使用時,沒什麼實際用處。

不過,通過將這種用法和 GET 選項配合, 就可以在不排序的情況下, 擷取多個外部鍵, 相當於執行一個整合的擷取操作(類似於 SQL 資料庫的 join 關鍵字)。

以下代碼示範了,如何在不引起排序的情況下,使用 SORT 、 BY 和 GET 擷取多個外部鍵:

redis 127.0.0.1:6379> SORT uid BY not-exists-key GET # GET user_level_* GET user_name_*1) "4"      # id2) "70"     # level3) "mary"   # name4) "3"5) "25"6) "peter"7) "2"8) "10"9) "jack"10) "1"11) "9999"12) "admin"

將雜湊表作為 GET 或 BY 的參數

除了可以將字串鍵之外, 雜湊表也可以作為 GET 或 BY 選項的參數來使用。

比如說,對於前面給出的使用者資訊表:

uid user_name_{uid} user_level_{uid}1 admin 99992 jack 103 peter 254 mary 70

我們可以不將使用者的名字和層級儲存在 user_name_{uid} 和 user_level_{uid} 兩個字串鍵中, 而是用一個帶有 name 域和 level 域的雜湊表 user_info_{uid} 來儲存使用者的名字和層級資訊:

redis 127.0.0.1:6379> HMSET user_info_1 name admin level 9999OKredis 127.0.0.1:6379> HMSET user_info_2 name jack level 10OKredis 127.0.0.1:6379> HMSET user_info_3 name peter level 25OKredis 127.0.0.1:6379> HMSET user_info_4 name mary level 70OK

之後, BY 和 GET 選項都可以用 key->field 的格式來擷取雜湊表中的域的值, 其中 key 表示雜湊表鍵, 而 field 則表示雜湊表的域:

redis 127.0.0.1:6379> SORT uid BY user_info_*->level1) "2"2) "3"3) "4"4) "1"redis 127.0.0.1:6379> SORT uid BY user_info_*->level GET user_info_*->name1) "jack"2) "peter"3) "mary"4) "admin"
五、儲存排序結果

預設情況下, SORT 操作只是簡單地返回排序結果,並不進行任何儲存操作。

通過給 STORE 選項指定一個 key 參數,可以將排序結果儲存到給定的鍵上。

如果被指定的 key 已存在,那麼原有的值將被排序結果覆蓋。

# 測試資料redis 127.0.0.1:6379> RPUSH numbers 1 3 5 7 9(integer) 5redis 127.0.0.1:6379> RPUSH numbers 2 4 6 8 10(integer) 10redis 127.0.0.1:6379> LRANGE numbers 0 -11) "1"2) "3"3) "5"4) "7"5) "9"6) "2"7) "4"8) "6"9) "8"10) "10"redis 127.0.0.1:6379> SORT numbers STORE sorted-numbers(integer) 10
# 排序後的結果redis 127.0.0.1:6379> LRANGE sorted-numbers 0 -11) "1"2) "2"3) "3"4) "4"5) "5"6) "6"7) "7"8) "8"9) "9"10) "10"

可以通過將 SORT 命令的執行結果儲存,並用 EXPIRE 為結果設定存留時間,以此來產生一個 SORT 操作的結果緩衝。

這樣就可以避免對 SORT 操作的頻繁調用:只有當結果集到期時,才需要再調用一次 SORT 操作。

另外,為了正確實現這一用法,你可能需要加鎖以避免多個用戶端同時進行緩衝重建(也就是多個用戶端,同一時間進行 SORT 操作,並儲存為結果集),具體參見 SETNX 命令。

可用版本:

    >= 1.0.0

時間複雜度:

    O(N+M*log(M)), N 為要排序的列表或集合內的元素數量, M 為要返回的元素數量。

    如果只是使用 SORT 命令的 GET 選項擷取資料而沒有進行排序,時間複雜度 O(N)。

傳回值:

    沒有使用 STORE 參數,返回列表形式的排序結果。

    使用 STORE 參數,返回排序結果的元素數量。


























































相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.