Redigo: إضافة دعم التجزئة

تم إنشاؤها على ٣٠ مارس ٢٠١٣  ·  7تعليقات  ·  مصدر: gomodule/redigo

لم أستطع الحصول على مكافئ Go + redigo لـ

HMSET myhash field1 "Hello" field2 "World"

للعمل ("عدد خاطئ من الوسائط لأمر" hmset "). سيكون دعم التجزئة الأصلي أمرًا رائعًا للتغلب على هذا وتوفير وظائف مريحة.

التعليق الأكثر فائدة

إليك مثال آخر يستخدم البنية بدلاً من الخريطة. يخزن هذا المثال البيانات بنفس تنسيق الأمثلة السابقة.

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...) لا يُجمع.

أي فكرة عما أفعله خطأ؟

توضح الأمثلة التالية كيفية إنشاء تجزئة واحدة لكل رمز.

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 هو خيار جيد آخر لتخزين البيانات المتداخلة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

lukasmalkmus picture lukasmalkmus  ·  18تعليقات

garyburd picture garyburd  ·  23تعليقات

mika picture mika  ·  5تعليقات

smotes picture smotes  ·  18تعليقات

Serhioromano picture Serhioromano  ·  7تعليقات