Sorted Set Operations
Redis Sorted Set is an ordered set where each member is associated with a score. The set is sorted by score.
ZAdd - Add Sorted Set Member
Add Member with Score
vb
oRedis.ZAdd "mysortedset", 100, "member1"
oRedis.ZAdd "mysortedset", 200, "member2"
oRedis.ZAdd "mysortedset", 150, "member3"Notes:
- Score can be integer or floating-point
- Members with same score are sorted lexicographically
- If member already exists, its score will be updated
ZRange - Get Members in Range
Get All Members (sorted by score ascending)
vb
Dim vMembers As Variant
vMembers = oRedis.ZRange("mysortedset", 0, -1)
If IsArray(vMembers) Then
Dim i As Long
For i = 0 To UBound(vMembers)
Debug.Print vMembers(i)
Next
End IfGet Members with Scores
vb
vMembers = oRedis.ZRange("mysortedset", 0, -1, True)
If IsArray(vMembers) Then
For i = 0 To UBound(vMembers) Step 2
If i + 1 <= UBound(vMembers) Then
Debug.Print vMembers(i) & ": " & vMembers(i + 1)
End If
Next
End IfGet Top N
vb
' Get top 3 (lowest 3 scores)
vMembers = oRedis.ZRange("mysortedset", 0, 2)Get Bottom N
vb
' Get bottom 3 (highest 3 scores)
vMembers = oRedis.ZRange("mysortedset", -3, -1)ZRem - Delete Sorted Set Member
vb
' Delete single member
oRedis.ZRem "mysortedset", "member1"
' Delete multiple members
oRedis.ZRem "mysortedset", "member2", "member3"ZCard - Get Sorted Set Member Count
vb
Dim lCount As Long
lCount = oRedis.ZCard("mysortedset")
Debug.Print "Sorted set member count: " & lCountUse Cases
1. Leaderboard
vb
Sub Leaderboard()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sLeaderboard As String
sLeaderboard = "leaderboard"
' Add player scores
oRedis.ZAdd sLeaderboard, 1000, "Player A"
oRedis.ZAdd sLeaderboard, 1500, "Player B"
oRedis.ZAdd sLeaderboard, 800, "Player C"
oRedis.ZAdd sLeaderboard, 2000, "Player D"
oRedis.ZAdd sLeaderboard, 1200, "Player E"
' Get leaderboard (sorted by score ascending)
Dim vRanking As Variant
vRanking = oRedis.ZRange(sLeaderboard, 0, -1)
Debug.Print "Leaderboard (ascending):"
Dim i As Long
If IsArray(vRanking) Then
For i = 0 To UBound(vRanking)
Debug.Print " " & (i + 1) & ". " & vRanking(i)
Next
End If
' Get leaderboard (with scores)
vRanking = oRedis.ZRange(sLeaderboard, 0, -1, True)
Debug.Print vbCrLf & "Leaderboard (with scores):"
If IsArray(vRanking) Then
For i = 0 To UBound(vRanking) Step 2
If i + 1 <= UBound(vRanking) Then
Debug.Print " " & vRanking(i) & ": " & vRanking(i + 1) & " points"
End If
Next
End If
' Get top 3
vRanking = oRedis.ZRange(sLeaderboard, 0, 2, True)
Debug.Print vbCrLf & "Top 3:"
If IsArray(vRanking) Then
For i = 0 To UBound(vRanking) Step 2
If i + 1 <= UBound(vRanking) Then
Debug.Print " Rank " & (i / 2 + 1) & ": " & vRanking(i) & " (" & vRanking(i + 1) & " points)"
End If
Next
End If
' Update player score
oRedis.ZAdd sLeaderboard, 2500, "Player A"
Debug.Print vbCrLf & "After updating Player A score:"
vRanking = oRedis.ZRange(sLeaderboard, -1, -1, True)
If IsArray(vRanking) Then
Debug.Print " First place: " & vRanking(0) & " (" & vRanking(1) & " points)"
End If
oRedis.DisConnect
End Sub2. Timeline
vb
Sub Timeline()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sTimeline As String
sTimeline = "timeline:events"
' Add events (use timestamp as score)
oRedis.ZAdd sTimeline, 1640995200, "Event 1: Project started"
oRedis.ZAdd sTimeline, 1640995800, "Event 2: Requirements analysis"
oRedis.ZAdd sTimeline, 1640996400, "Event 3: Design completed"
oRedis.ZAdd sTimeline, 1640997000, "Event 4: Development started"
oRedis.ZAdd sTimeline, 1640997600, "Event 5: Testing phase"
' Get events sorted by time
Dim vEvents As Variant
vEvents = oRedis.ZRange(sTimeline, 0, -1, True)
Debug.Print "Timeline:"
Dim i As Long
If IsArray(vEvents) Then
For i = 0 To UBound(vEvents) Step 2
If i + 1 <= UBound(vEvents) Then
Dim lTimestamp As Long
lTimestamp = CLng(vEvents(i + 1))
Debug.Print " " & FormatDateTime(lTimestamp) & " - " & vEvents(i)
End If
Next
End If
oRedis.DisConnect
End Sub
Function FormatDateTime(ByVal lTimestamp As Long) As String
' Convert Unix timestamp to datetime string
Dim dtDate As Date
dtDate = DateAdd("s", lTimestamp, #1/1/1970#)
FormatDateTime = Format(dtDate, "yyyy-mm-dd hh:nn:ss")
End Function3. Delayed Queue
vb
Sub DelayedQueue()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sQueue As String
sQueue = "queue:delayed"
' Add tasks (use execution time as score)
Dim lNow As Long
lNow = Timer ' Current seconds (simplified)
oRedis.ZAdd sQueue, lNow + 60, "Task 1: Execute in 1 minute"
oRedis.ZAdd sQueue, lNow + 120, "Task 2: Execute in 2 minutes"
oRedis.ZAdd sQueue, lNow + 30, "Task 3: Execute in 30 seconds"
' Simulate time passing
Dim i As Long
For i = 1 To 5
lNow = Timer
' Get expired tasks
Dim vTasks As Variant
vTasks = oRedis.ZRange(sQueue, 0, 0, True)
If IsArray(vTasks) And UBound(vTasks) >= 1 Then
Dim lTaskTime As Long
lTaskTime = CLng(vTasks(1))
If lTaskTime <= lNow Then
Debug.Print "Execute task: " & vTasks(0)
oRedis.ZRem sQueue, vTasks(0)
End If
End If
' Wait one second
Application.Wait (Now + TimeValue("0:00:01"))
Next
oRedis.DisConnect
End Sub4. Popularity Ranking
vb
Sub HotArticles()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sHotKey As String
sHotKey = "hot:articles"
' Simulate article view counts
oRedis.ZAdd sHotKey, 1000, "article:1"
oRedis.ZAdd sHotKey, 2500, "article:2"
oRedis.ZAdd sHotKey, 800, "article:3"
oRedis.ZAdd sHotKey, 3000, "article:4"
oRedis.ZAdd sHotKey, 1500, "article:5"
' Get top 10 hot articles
Dim vHotArticles As Variant
vHotArticles = oRedis.ZRange(sHotKey, -10, -1, True)
Debug.Print "Hot Articles TOP 10:"
Dim i As Long, lIndex As Long
lIndex = 1
If IsArray(vHotArticles) Then
For i = UBound(vHotArticles) To 0 Step -2
If i - 1 >= 0 Then
Debug.Print " " & lIndex & ". " & vHotArticles(i - 1) & " (" & vHotArticles(i) & " views)"
lIndex = lIndex + 1
End If
Next
End If
' Article viewed, increase popularity
Dim sArticle As String
sArticle = "article:1"
' Get current score
Dim lCurrentScore As Long
lCurrentScore = CLng(oRedis.Get_(sArticle))
lCurrentScore = lCurrentScore + 1
' Update score
oRedis.ZAdd sHotKey, lCurrentScore, sArticle
Debug.Print vbCrLf & "Article " & sArticle & " popularity updated after view"
oRedis.DisConnect
End Sub5. Priority Queue
vb
Sub PriorityQueue()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sQueue As String
sQueue = "queue:priority"
' Add tasks (use priority as score, higher priority has lower score)
oRedis.ZAdd sQueue, 1, "Urgent task: Fix production bug"
oRedis.ZAdd sQueue, 3, "Normal task: Write documentation"
oRedis.ZAdd sQueue, 2, "Important task: Code review"
oRedis.ZAdd sQueue, 1, "Urgent task: Database maintenance"
' Get highest priority task
Dim vTask As Variant
vTask = oRedis.ZRange(sQueue, 0, 0)
If IsArray(vTask) Then
Debug.Print "Highest priority task: " & vTask(0)
End If
' Process tasks
Debug.Print vbCrLf & "Processing order:"
While oRedis.ZCard(sQueue) > 0
vTask = oRedis.ZRange(sQueue, 0, 0)
If IsArray(vTask) Then
Debug.Print " " & vTask(0)
oRedis.ZRem sQueue, vTask(0)
End If
Wend
oRedis.DisConnect
End Sub6. Rating System
vb
Sub RatingSystem()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then Exit Sub
Dim sProductId As String
sProductId = "product:1001"
' User ratings
oRedis.ZAdd sProductId & ":ratings", 5, "user:1"
oRedis.ZAdd sProductId & ":ratings", 4, "user:2"
oRedis.ZAdd sProductId & ":ratings", 5, "user:3"
oRedis.ZAdd sProductId & ":ratings", 3, "user:4"
oRedis.ZAdd sProductId & ":ratings", 4, "user:5"
' Get all ratings
Dim vRatings As Variant
vRatings = oRedis.ZRange(sProductId & ":ratings", 0, -1, True)
Debug.Print "All ratings:"
Dim i As Long
Dim dSum As Double
dSum = 0
If IsArray(vRatings) Then
For i = 0 To UBound(vRatings) Step 2
If i + 1 <= UBound(vRatings) Then
Dim lRating As Long
lRating = CLng(vRatings(i + 1))
Debug.Print " " & vRatings(i) & ": " & lRating & " stars"
dSum = dSum + lRating
End If
Next
End If
' Calculate average rating
Dim lCount As Long
lCount = oRedis.ZCard(sProductId & ":ratings")
Dim dAverage As Double
dAverage = dSum / lCount
Debug.Print vbCrLf & "Average rating: " & Format(dAverage, "0.00") & " stars (" & lCount & " ratings)"
oRedis.DisConnect
End SubComplete Example
vb
Sub Example_SortedSets()
Dim oRedis As New cRedisClient
If Not oRedis.Connect() Then
Debug.Print "Connection failed: " & oRedis.LastError
Exit Sub
End If
' Use Sorted Set to store leaderboard
oRedis.ZAdd "leaderboard", 1000, "Player A"
oRedis.ZAdd "leaderboard", 1500, "Player B"
oRedis.ZAdd "leaderboard", 800, "Player C"
oRedis.ZAdd "leaderboard", 2000, "Player D"
Debug.Print "Leaderboard (sorted by score ascending):"
Dim vPlayers As Variant
vPlayers = oRedis.ZRange("leaderboard", 0, -1)
Dim i As Long
If IsArray(vPlayers) Then
For i = 0 To UBound(vPlayers)
Debug.Print " " & (i + 1) & ". " & vPlayers(i)
Next
End If
Debug.Print vbCrLf & "Leaderboard (with scores):"
vPlayers = oRedis.ZRange("leaderboard", 0, -1, True)
If IsArray(vPlayers) Then
For i = 0 To UBound(vPlayers) Step 2
If i + 1 <= UBound(vPlayers) Then
Debug.Print " " & vPlayers(i) & ": " & vPlayers(i + 1) & " points"
End If
Next
End If
' Get sorted set member count
Debug.Print vbCrLf & "Player count: " & oRedis.ZCard("leaderboard")
oRedis.DisConnect
End SubSorted Set Features
- Ordered: Automatically sorted by score
- Unique: Members are unique, but scores can be the same
- Updateable: Can update member scores
- Range queries: Supports querying members within score range
- High performance: Insert and query operations have O(log N) complexity
Usage Recommendations
- Leaderboard: Use scores to store ratings,
ZRangeto get rankings - Timeline: Use timestamp as score
- Priority queue: Use priority as score
- Range queries: Can query members within specific score range