Go + redigoに相当するものを取得できませんでした
HMSET myhash field1 "Hello" field2 "World"
動作する(「 'hmset'コマンドの引数の数が間違っているERR」)。 ネイティブハッシュサポートは、これを回避して便利な関数を提供するのに便利です。
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つの優れたオプションです。
最も参考になるコメント
mapの代わりにstructを使用する別の例を次に示します。 この例では、前の例と同じ形式でデータを保存します。