Saya tidak bisa mendapatkan Go + redigo yang setara dengan
HMSET myhash field1 "Hello" field2 "World"
untuk bekerja ("ERR salah jumlah argumen untuk perintah 'hmset'"). Dukungan hash asli akan menyenangkan untuk menyiasatinya dan memberikan fungsi kenyamanan.
Redigo dapat menjalankan perintah apa pun termasuk HMSET. Bisakah Anda membagikan baris kode tempat Anda memanggil 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)
}
Komentar mengungkapkan versi lain yang juga saya coba, seperti mengirim (hampir) semua perintah sekaligus dengan conn.Send("HMSET", cmd...)
. conn.Send("HMSET", "stocks", cmd...)
tidak dapat dikompilasi.
Tahu apa yang saya lakukan salah?
Contoh berikut menunjukkan cara membuat satu hash untuk setiap simbol.
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)
}
}
}
Berikut contoh lain yang menggunakan struct alih-alih map. Contoh ini menyimpan data dalam format yang sama seperti contoh sebelumnya.
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)
}
}
Contoh yang bagus, terima kasih! Saya membaca lagi dan sepertinya Redis tidak mendukung hash bersarang, jadi saya kira apa yang saya coba lakukan tidak akan berhasil: membuat satu hash Redis yang berisi hash lain dari simbol hingga data stok. Saya dapat mencoba peretasan yang mungkin cukup baik untuk menyimpan beberapa JSON sebagai string karena itulah yang saya butuhkan.
Dengan satu atau lain cara, saya akan dapat membuat ini berhasil, terutama dengan contoh-contoh yang Anda berikan. Terima kasih lagi!
Hash bersarang tidak didukung. The Little Redis Book yang gratis dan singkat memberikan gambaran yang bagus tentang jenis-jenis yang didukung oleh Redis.
Itu umum untuk menyimpan JSON di Redis. Jika Anda hanya mengakses data dari Go, maka encoding/gob adalah pilihan bagus lainnya untuk menyimpan data bersarang.
Komentar yang paling membantu
Berikut contoh lain yang menggunakan struct alih-alih map. Contoh ini menyimpan data dalam format yang sama seperti contoh sebelumnya.