Redigo: Hash-Unterstützung hinzufügen

Erstellt am 30. März 2013  ·  7Kommentare  ·  Quelle: gomodule/redigo

Ich konnte das Go + Redigo-Äquivalent von nicht bekommen

HMSET myhash field1 "Hello" field2 "World"

um zu funktionieren ("ERR falsche Anzahl von Argumenten für den Befehl 'hmset'"). Native Hash-Unterstützung wäre schön, um dies zu umgehen und Komfortfunktionen bereitzustellen.

Hilfreichster Kommentar

Hier ist ein weiteres Beispiel, das struct anstelle von map verwendet. In diesem Beispiel werden die Daten im gleichen Format wie in den vorherigen Beispielen gespeichert.

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)
    }
}

Alle 7 Kommentare

Redigo kann jeden Befehl ausführen, einschließlich HMSET. Können Sie die Codezeile freigeben, in der Sie HMSET aufrufen?

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)
}

Die Kommentare zeigen die anderen Versionen, die ich auch ausprobiert habe, wie z. B. das Senden (fast) aller Befehle auf einmal mit conn.Send("HMSET", cmd...) . conn.Send("HMSET", "stocks", cmd...) kompiliert nicht.

Irgendeine Ahnung was ich falsch mache?

Die folgenden Beispiele zeigen, wie Sie für jedes Symbol einen Hash erstellen.

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)
        }
    }
}

Hier ist ein weiteres Beispiel, das struct anstelle von map verwendet. In diesem Beispiel werden die Daten im gleichen Format wie in den vorherigen Beispielen gespeichert.

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)
    }
}

Tolle Beispiele, danke! Ich lese noch mehr und es hört sich so an, als ob Redis keine verschachtelten Hashes unterstützt. Ich kann den wahrscheinlich gut genug Hack versuchen, etwas JSON als String zu speichern, da ich das wirklich brauche.

So oder so werde ich es schaffen, vor allem mit den Beispielen, die Sie gegeben haben. Danke noch einmal!

Verschachtelte Hashes werden nicht unterstützt. Das kostenlose und kurze The Little Redis Book gibt einen schönen Überblick über die von Redis unterstützten Typen.

Es ist üblich, JSON in Redis zu speichern. Wenn Sie nur von Go aus auf die Daten zugreifen, ist Encoding/gob eine weitere gute Option zum Speichern verschachtelter Daten.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

Serhioromano picture Serhioromano  ·  7Kommentare

jney picture jney  ·  17Kommentare

V2Vz picture V2Vz  ·  4Kommentare

mika picture mika  ·  5Kommentare

samwhitecoull picture samwhitecoull  ·  3Kommentare