Redigo: ハッシュサポートを追加

作成日 2013年03月30日  ·  7コメント  ·  ソース: gomodule/redigo

Go + redigoに相当するものを取得できませんでした

HMSET myhash field1 "Hello" field2 "World"

動作する(「 'hmset'コマンドの引数の数が間違っているERR」)。 ネイティブハッシュサポートは、これを回避して便利な関数を提供するのに便利です。

最も参考になるコメント

mapの代わりにstructを使用する別の例を次に示します。 この例では、前の例と同じ形式でデータを保存します。

package main

import (
    "github.com/garyburd/redigo/redis"
    "log"
)

type Stock struct {
    CompanyName string `redis:"company_name"`
    OpenPrice   string `redis:"open_price"`
    AskPrice    string `redis:"ask_price"`
    ClosePrice  string `redis:"close_price"`
    BidPrice    string `redis:"bid_price"`
}

func main() {
    conn, err := redis.Dial("tcp", ":6379")
    if err != nil {
        log.Fatalf("Couldn't connect to Redis: %v\n", err)
    }
    defer conn.Close()

    stockData := map[string]*Stock{
        "GOOG": &Stock{CompanyName: "Google Inc.", OpenPrice: "803.99", AskPrice: "795.50", ClosePrice: "802.66", BidPrice: "793.36"},
        "MSFT": &Stock{AskPrice: "N/A", OpenPrice: "28.30", CompanyName: "Microsoft Corpora", BidPrice: "28.50", ClosePrice: "28.37"},
    }

    for sym, row := range stockData {
        if _, err := conn.Do("HMSET", redis.Args{sym}.AddFlat(row)...); err != nil {
            log.Fatal(err)
        }
    }

    for sym := range stockData {
        values, err := redis.Values(conn.Do("HGETALL", sym))
        if err != nil {
            log.Fatal(err)
        }
        var stock Stock
        if err := redis.ScanStruct(values, &stock); err != nil {
            log.Fatal(err)
        }
        log.Printf("%s: %+v", sym, &stock)
    }
}

全てのコメント7件

Redigoは、HMSETを含むすべてのコマンドを実行できます。 HMSETを呼び出すコード行を共有できますか?

package main

import (
    "fmt"
    "github.com/garyburd/redigo/redis"
    "log"
)

var (
    conn redis.Conn
)

// Connect to Redis
func init() {
    var err error
    conn, err = redis.Dial("tcp", ":6379")
    if err != nil {
        log.Fatalf("Couldn't connect to Redis: %v\n", err)
    }
}

func main() {
    defer conn.Close()

    stockData := map[string]map[string]string{
        "GOOG": {"company_name":"Google Inc.", "open_price":"803.99", "ask_price":"795.50", "close_price":"802.66", "bid_price":"793.36"},
        "MSFT": {"ask_price":"N/A", "open_price":"28.30", "company_name":"Microsoft Corpora", "bid_price":"28.50", "close_price":"28.37"},
    }

    conn.Send("HMSET", "stocks")
    // conn.Send("HMSET")
    // conn.Send("stocks")
    // var cmd []interface{}
    for sym, row := range stockData {
        for colName, val := range row {
            key := sym + ":" + colName
            // cmd = append(cmd, key, val)
            conn.Send(key, val)
        }
    }
    // conn.Send("HMSET", cmd...)
    reply, err := conn.Do("EXEC")
    if err != nil {
        log.Fatalf("Error setting hash: %v\n", err)
    }
    fmt.Printf("reply == %+v\n", reply)
}

コメントは、 conn.Send("HMSET", cmd...)して(ほぼ)すべてのコマンドを一度に送信するなど、私が試した他のバージョンを示しています。 conn.Send("HMSET", "stocks", cmd...)はコンパイルされません。

私が間違っていることについて何か考えはありますか?

次の例は、シンボルごとに1つのハッシュを作成する方法を示しています。

package main

import (
    "github.com/garyburd/redigo/redis"
    "log"
)

func main() {
    conn, err := redis.Dial("tcp", ":6379")
    if err != nil {
        log.Fatalf("Couldn't connect to Redis: %v\n", err)
    }
    defer conn.Close()

    stockData := map[string]map[string]string{
        "GOOG": {"company_name": "Google Inc.", "open_price": "803.99", "ask_price": "795.50", "close_price": "802.66", "bid_price": "793.36"},
        "MSFT": {"ask_price": "N/A", "open_price": "28.30", "company_name": "Microsoft Corpora", "bid_price": "28.50", "close_price": "28.37"},
    }

    // Example 1: Write command arguments out explicitly.

    for sym, row := range stockData {
        if _, err := conn.Do("HMSET", sym,
            "company_name", row["company_name"],
            "open_price", row["open_price"],
            "ask_price", row["ask_price"],
            "bid_price", row["bid_price"]); err != nil {
            log.Fatal(err)
        }
    }

    printAndDel(conn, "example 1", stockData)

    // Example 2: Construct command arguments using range over a row map.

    for sym, row := range stockData {
        args := []interface{}{sym}
        for k, v := range row {
            args = append(args, k, v)
        }
        if _, err := conn.Do("HMSET", args...); err != nil {
            log.Fatal(err)
        }
    }

    printAndDel(conn, "example 2", stockData)

    // Example 3: Construct command arguments using Redigo helper function.

    for sym, row := range stockData {
        if _, err := conn.Do("HMSET", redis.Args{sym}.AddFlat(row)...); err != nil {
            log.Fatal(err)
        }
    }

    printAndDel(conn, "example 3", stockData)
}

func printAndDel(conn redis.Conn, message string, stockData map[string]map[string]string) {
    log.Print(message)
    for sym := range stockData {
        values, err := redis.Values(conn.Do("HGETALL", sym))
        if err != nil {
            log.Fatal(err)
        }
        log.Print(sym)
        for i := 0; i < len(values); i += 2 {
            log.Printf("  %s: %s", values[i], values[i+1])
        }
    }
    for sym := range stockData {
        if _, err := conn.Do("DEL", sym); err != nil {
            log.Fatal(err)
        }
    }
}

mapの代わりにstructを使用する別の例を次に示します。 この例では、前の例と同じ形式でデータを保存します。

package main

import (
    "github.com/garyburd/redigo/redis"
    "log"
)

type Stock struct {
    CompanyName string `redis:"company_name"`
    OpenPrice   string `redis:"open_price"`
    AskPrice    string `redis:"ask_price"`
    ClosePrice  string `redis:"close_price"`
    BidPrice    string `redis:"bid_price"`
}

func main() {
    conn, err := redis.Dial("tcp", ":6379")
    if err != nil {
        log.Fatalf("Couldn't connect to Redis: %v\n", err)
    }
    defer conn.Close()

    stockData := map[string]*Stock{
        "GOOG": &Stock{CompanyName: "Google Inc.", OpenPrice: "803.99", AskPrice: "795.50", ClosePrice: "802.66", BidPrice: "793.36"},
        "MSFT": &Stock{AskPrice: "N/A", OpenPrice: "28.30", CompanyName: "Microsoft Corpora", BidPrice: "28.50", ClosePrice: "28.37"},
    }

    for sym, row := range stockData {
        if _, err := conn.Do("HMSET", redis.Args{sym}.AddFlat(row)...); err != nil {
            log.Fatal(err)
        }
    }

    for sym := range stockData {
        values, err := redis.Values(conn.Do("HGETALL", sym))
        if err != nil {
            log.Fatal(err)
        }
        var stock Stock
        if err := redis.ScanStruct(values, &stock); err != nil {
            log.Fatal(err)
        }
        log.Printf("%s: %+v", sym, &stock)
    }
}

素晴らしい例、ありがとう! もう少し読んでみると、Redisはネストされたハッシュをサポートしていないようです。そのため、私がやろうとしていたことはうまくいかないと思います。シンボルからストックデータまでの別のハッシュを含む1つのRedisハッシュを作成します。 JSONを文字列として保存するという、おそらく十分なハックを試してみるかもしれません。それが本当に必要なことだからです。

いずれにせよ、特にあなたが与えた例で、私はこの仕事をすることができるでしょう。 再度、感謝します!

ネストされたハッシュはサポートされていません。 無料で短いTheLittle Redis Bookには、Redisでサポートされているタイプの概要が記載されています。

JSONをRedisに保存するのが一般的です。 Goからのデータにのみアクセスしている場合は、 encoding / gobがネストされたデータを格納するためのもう1つの優れたオプションです。

このページは役に立ちましたか?
0 / 5 - 0 評価