لم أستطع الحصول على مكافئ Go + redigo لـ
HMSET myhash field1 "Hello" field2 "World"
للعمل ("عدد خاطئ من الوسائط لأمر" hmset "). سيكون دعم التجزئة الأصلي أمرًا رائعًا للتغلب على هذا وتوفير وظائف مريحة.
يمكن لـ 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...)
لا يُجمع.
أي فكرة عما أفعله خطأ؟
توضح الأمثلة التالية كيفية إنشاء تجزئة واحدة لكل رمز.
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)
}
}
}
إليك مثال آخر يستخدم البنية بدلاً من الخريطة. يخزن هذا المثال البيانات بنفس تنسيق الأمثلة السابقة.
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 لا يدعم التجزئة المتداخلة ، لذلك أفترض أن ما كنت أحاول القيام به لن ينجح: إنشاء تجزئة Redis تحتوي على تجزئة أخرى من الرموز إلى بيانات المخزون. قد أجرب الاختراق الذي ربما يكون جيدًا بما يكفي لتخزين بعض JSON كسلسلة لأن هذا ما أحتاجه حقًا.
بطريقة أو بأخرى ، سأكون قادرًا على جعل هذا العمل ، خاصة مع الأمثلة التي قدمتها. شكرا لك مرة أخرى!
التجزئات المتداخلة غير مدعومة. يقدم كتاب The Little Redis المجاني والقصير نظرة عامة لطيفة على الأنواع التي يدعمها Redis.
من الشائع تخزين JSON في Redis. إذا كنت تصل إلى البيانات من Go فقط ، فإن الترميز / gob هو خيار جيد آخر لتخزين البيانات المتداخلة.
التعليق الأكثر فائدة
إليك مثال آخر يستخدم البنية بدلاً من الخريطة. يخزن هذا المثال البيانات بنفس تنسيق الأمثلة السابقة.