Skip to content

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 If

Get 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 If

Get 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: " & lCount

Use 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 Sub

2. 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 Function

3. 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 Sub

4. 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 Sub

5. 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 Sub

6. 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 Sub

Complete 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 Sub

Sorted Set Features

  1. Ordered: Automatically sorted by score
  2. Unique: Members are unique, but scores can be the same
  3. Updateable: Can update member scores
  4. Range queries: Supports querying members within score range
  5. High performance: Insert and query operations have O(log N) complexity

Usage Recommendations

  1. Leaderboard: Use scores to store ratings, ZRange to get rankings
  2. Timeline: Use timestamp as score
  3. Priority queue: Use priority as score
  4. Range queries: Can query members within specific score range

VB6 and LOGO copyright of Microsoft Corporation