使用Redigo (2) 处理各种数据类型

首先

我们来看一下Redis的Go语言客户端库Redigo的使用方法。本文介绍了各种数据类型的处理方式。

Redis有以下五种数据类型。

    • 文字列型

 

    • リスト型

 

    • セット型

 

    • ソート済みセット型

 

    ハッシュ型

在(1)的文章中,我已经了解了有关字符串类型的信息。在本文中,我们将探讨Redigo的基本用法,并介绍其他四种类型。

环境

    • OS: Windows 10

 

    • Redis: win-3.2.100

Go言語: 1.11

列表类型

列表类型是指字符串类型的双向列表。命令列表请参考参考资料。首先进行简单的元素添加和获取操作。

package main

import (
    "fmt"

    "github.com/gomodule/redigo/redis"
)

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 要素の追加
    _, err = conn.Do("RPUSH", "seasons", "spring")
    _, err = conn.Do("RPUSH", "seasons", "summer")
    _, err = conn.Do("RPUSH", "seasons", "autumn")
    _, err = conn.Do("RPUSH", "seasons", "winter")

    // 要素の取得
    a, err := redis.String(conn.Do("LINDEX", "seasons", 2))
    if err != nil {
        panic(err)
    }
    fmt.Println(a) // autumn

    // 全体の取得
    s, err := redis.Strings(conn.Do("LRANGE", "seasons", 0, -1))
    if err != nil {
        panic(err)
    }
    fmt.Println(s) // [spring summer autumn winter]
}

RPUSH是一个命令,用于将元素添加到列表的末尾(这里省略了返回值检查)。我们正在向名为”seasons”的键的列表中添加了四个元素。
LINDEX是一个命令,用于返回列表中由索引指定的元素。
LRANGE是一个命令,用于返回列表中由两个索引指定范围内的元素。”0″表示起始位置,”-1″表示末尾位置(即返回所有元素)。我们还将结果传递给redis.Strings。这是一个将conn.Do的结果转换为[]string的实用函数。

要素的删除可以按照以下方式进行。

package main

import (
    "fmt"

    "github.com/gomodule/redigo/redis"
)

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 要素の追加
    _, err = conn.Do("RPUSH", "words", "xxxxxx")
    _, err = conn.Do("RPUSH", "words", "yyy")
    _, err = conn.Do("RPUSH", "words", "z")
    _, err = conn.Do("RPUSH", "words", "xxxxxx")

    // 要素の削除(先頭に近いxxxxxxを1個だけ消す)
    n, err := redis.Int(conn.Do("LREM", "words", 1, "xxxxxx"))
    if err != nil {
        panic(err)
    }
    fmt.Println(n) // 1

    // 要素の削除(先頭の要素を消す)
    a, err := redis.String(conn.Do("LPOP", "words"))
    if err != nil {
        panic(err)
    }
    fmt.Println(a) // yyy

    // 全体の取得
    s, err := redis.Strings(conn.Do("LRANGE", "words", 0, -1))
    if err != nil {
        panic(err)
    }
    fmt.Println(s) // [z xxxxxx]
}

在将四个字符串添加到名为words的键列表之后,使用LREM和LPOP进行元素删除。

LREM命令会从列表头开始查找并删除指定值的指定数量的元素。在此情况下,将删除最先添加的xxxxxx元素。返回值为已删除的元素数量。通过redis.Int将结果转换为Go语言的int类型。

LPOP函数用于删除列表的首个元素。在此操作后,列表的状态变为[yyy, z, xxxxxx],因此首个元素yyy被删除。函数返回被删除的元素。我们将其传递给redis.String,然后将其转换为Go中的string类型。

这次我没有介绍,但是列表类型的命令还有其他的选项,比如LTRIM可以从开头和末尾截取元素,LSET可以修改特定元素的值,RPOPLPUSH可以在两个列表之间移动元素。

套装类型

集合类型是一种字符串类型的集合。与列表类型不同,集合类型不允许有重复的元素。请参考参考资料中的命令列表。以下展示了一系列关于添加、删除和获取元素的操作流程。

package main

import (
    "fmt"

    "github.com/gomodule/redigo/redis"
)

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 要素の追加
    _, err = conn.Do("SADD", "numbers", "one")
    _, err = conn.Do("SADD", "numbers", "two")
    _, err = conn.Do("SADD", "numbers", "three")
    _, err = conn.Do("SADD", "numbers", "four")

    // 要素の追加(既に追加済み)
    n, err := redis.Int(conn.Do("SADD", "numbers", "one"))
    if err != nil {
        panic(err)
    }
    fmt.Println(n) // 0

    // 要素の削除
    m, err := redis.Int(conn.Do("SREM", "numbers", "three"))
    if err != nil {
        panic(err)
    }
    fmt.Println(m) // 1

    // 要素の存在確認
    k, err := redis.Int(conn.Do("SISMEMBER", "numbers", "five"))
    if err != nil {
        panic(err)
    }
    fmt.Println(k) // 0

    // 全体の取得
    s, err := redis.Strings(conn.Do("SMEMBERS", "numbers"))
    if err != nil {
        panic(err)
    }
    fmt.Println(s) // [one two four]
}

SADD会向集合中添加元素。如果尝试重新添加已经存在的元素,则返回值将为0(成功时返回1)。
SREM会从集合中返回指定的元素。
SISMEMBER会返回指定的元素是否存在于集合中。如果存在则返回1,否则返回0。
SMEMBERS会获取集合中的所有元素。

关于集合命令,除了还有随机删除元素的SPOP命令(什么时候用呢?),获取元素个数的SCARD命令,以及在两个集合之间移动元素的SMOVE命令等。此外,还有多个集合的交集(SINTER)和并集(SUNION),以及差集(SDIFF)等集合运算相关的命令都很丰富。

已排序的集合类型

已排序的集合是根据分数进行排序的字符串集合。我认为它类似于C++中的std::multimap<float,string>类型。请参考命令列表。以下是以5名学生的考试成绩为主题的常见操作示例。

package main

import (
    "fmt"

    "github.com/gomodule/redigo/redis"
)

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 要素の追加
    _, err = conn.Do("ZADD", "math_test", 60, "alice")
    _, err = conn.Do("ZADD", "math_test", 50, "bob")
    _, err = conn.Do("ZADD", "math_test", 100, "charlie")
    _, err = conn.Do("ZADD", "math_test", 10, "dave")
    _, err = conn.Do("ZADD", "math_test", 20, "eve")

    // 最低スコアの要素(とそのスコア)を得る
    s, err := redis.Strings(conn.Do("ZRANGE", "math_test", 0, 0, "WITHSCORES"))
    if err != nil {
        panic(err)
    }
    fmt.Println(s) // [dave 10]

    // スコア40以上70以下の要素(とそのスコア)を得る
    t, err := redis.Strings(conn.Do("ZRANGEBYSCORE", "math_test", 40, 70, "WITHSCORES"))
    if err != nil {
        panic(err)
    }
    fmt.Println(t) // [bob 50 alice 60]

    // スコアが小さい順に要素を2個削除する
    n, err := redis.Int(conn.Do("ZREMRANGEBYRANK", "math_test", 0, 1))
    if err != nil {
        panic(err)
    }
    fmt.Println(n) // 2

    // 全体の取得
    u, err := redis.Strings(conn.Do("ZREVRANGE", "math_test", 0, -1))
    if err != nil {
        panic(err)
    }
    fmt.Println(u) // [charlie alice bob]
}

元素将以点数从低到高的顺序进行排序并保持。

ランク01234スコア10205060100値daveevebobalicecharlie

如果要获取特定排名的学生,可以使用ZRANGE。例如,当指定ZRANGE 0, 0时,将获得排名在0或更高且排名在0或更低的学生,也就是最低分的学生(以0索引)。如果指定WITHSCORES选项,还可以同时获取分数。相反,如果想获取最高分的学生,可以使用ZREVRANGE。
当根据分数范围筛选时,可以使用ZRANGEBYSCORE。例如,当指定ZRANGEBYSCORE 40, 70时,将获得分数在40或更高且分数在70或更低的元素。
要删除元素,可以使用ZREMRANGEBYRANK。ZREMRANGEBYRANK 0, 1表示删除排名在0或更高且排名在1或更低的学生,也就是删除dave和eve。

哈希类型

哈希类型是一个映射字符串类型的对(字段和值)。我认为它类似于Python的字典类型(值仅限于字符串)。请参考命令列表以获取更多信息。以下是一个示例,展示了如何向名为profile的键添加或更新字段和值的对。

package main

import (
    "fmt"

    "github.com/gomodule/redigo/redis"
)

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 要素の追加
    _, err = conn.Do("HSET", "profile", "name", "yamada")
    _, err = conn.Do("HSET", "profile", "age", "30")
    _, err = conn.Do("HSET", "profile", "country", "america")

    // 要素の追加と更新
    t, err := redis.String(conn.Do("HMSET", "profile", "country", "japan", "city", "tokyo"))
    if err != nil {
        panic(err)
    }
    fmt.Println(t) // OK

    // 要素の取得
    s, err := redis.String(conn.Do("HGET", "profile", "country"))
    if err != nil {
        panic(err)
    }
    fmt.Println(s) // japan

    // 値をインクリメントする
    n, err := redis.Int(conn.Do("HINCRBY", "profile", "age", "2"))
    if err != nil {
        panic(err)
    }
    fmt.Println(n) // 32

    // 全体の取得
    u, err := redis.Strings(conn.Do("HGETALL", "profile"))
    if err != nil {
        panic(err)
    }
    fmt.Println(u) // [name yamada age 32 country japan city tokyo]
}

使用HSET来添加字段和值。在这里,我们丢弃了返回值,但如果字段已经存在,则返回0(值将被覆盖),如果不存在,则返回1。
您也可以使用HMSET添加多对字段和值。您可以交替列出字段1、值1、字段2、值2等。
您还可以使用HINCRBY来增加或减少值。值必须在64位带符号整数范围内。
您还可以使用HGETALL来获取所有的字段和值,它们会交替出现。

最后

我们将在Redigo中看到如何处理Redis的各种数据类型。

请参考

    • Redigoを使う(1) 基本的な使い方

 

    • Redigoを使う(3) トランザクションを行う

 

    • Redigoを使う(4) コネクションプールを使う

 

    • Redigoを使う(5) ユーティリティ関数

 

    Redigoを使う(6) パブリッシュ/サブスクライブ
广告
将在 10 秒后关闭
bannerAds