How to scan keys from redis using golang using "SCAN" not "KEYS"

Issue

This is My Code

redisPool := redis.NewPool(func() (redis.Conn, error) {
        con, err := redis.Dial("tcp", *redisAddress)
        con.Do("SELECT", 0)
        if err != nil {
            return nil, err
        }
        return con, err
    }, *maxConnections)
    fmt.Println("Redis Connection Establ...!")
    con := redisPool.Get()
    data, err1 := con.Do("scan", "0")
    //data, err1 := con.Do("KEYS", "*")
    if err1 != nil {
        fmt.Println(err1)
    } else {
        fmt.Println(reflect.TypeOf(data))
        fmt.Println(data)
    }

my output is not coming in string

Solution

The thing about the SCAN command is that it doesn’t just return a bunch of keys, but it returns an "iterator" number that you should put in your next call to SCAN. so the structure of the reply can be seen as

[ iterator, [k1, k2, ... k10] ]

You start by calling SCAN 0 and in consecutive calls you need to call SCAN <iterator>.

Doing this using redigo goes like this (my error handling is incorrect, but this is just to show the idea):

// here we'll store our iterator value
iter := 0

// this will store the keys of each iteration
var keys []string
for {

    // we scan with our iter offset, starting at 0
    if arr, err := redis.Values(conn.Do("SCAN", iter)); err != nil {
        panic(err)
    } else {

        // now we get the iter and the keys from the multi-bulk reply
        iter, _ = redis.Int(arr[0], nil)
        keys, _ = redis.Strings(arr[1], nil)
    }
    
    fmt.Println(keys)
    
    // check if we need to stop...
    if iter == 0  {
        break
    }
}

Answered By – Not_a_Golfer

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.