使用redigo将Redson中的json部分转换为来自Redis的Go结构

时间:2015-05-10 10:05:23

标签: json go redis redigo

我有一个由浏览器发布的json。它是

的哈希
var id int64 = 123 

,比方说三个字段如下:

myJson := `{ 
    "a":"{'x1':'apple','x2':'orange'}", 
    "b":"{'y1':345678,'y2':32456}", 
    "c":"['alpha@example1.com', 'beta@example2.com']"}`

然后使用 redigo 并使用以下命令将其存储在Redis中:

HMSET id:123 a "{'x1':'apple','x2':'orange'}" b "{'y1':345678,'y2':32456}" c "['alpha@example1.com', 'beta@example2.com']"

现在,我想在Go

中使用这样的模型
type Model struct {
    A string `json:"a"`
    B string `json:"b"`
    C string `json:"c"` // Unknown length of map at runtime
}

1。我用

打电话给Redis
v, _ := redis.Values(c.Do("HGETALL", "id:123"))

我通过redis-cli看到正确存储的值,但将 v 回复转换为模型结构不起作用:

var model Model
if err := redis.ScanStruct(v, &model); err != nil {
    panic(err)
}
fmt.Printf("c %#v\n", model.C) => empty []

我想访问单独的k:v对,如:

B.y2 = 32456
C[0] = "alpha@example1.com"

2。我还想将json.Marshal myJson 作为{a},{a,b},{a,c的组合返回浏览器},{a,b,c}等我不确定如何将各种a,b,c场组合组合成一个要编组的组合。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:2)

首先,您应该使用redis而非json标记标记您的字段名称,这是redigo用于ScanStruct()的标记。 e.g

type Model struct {
    A string `redis:"a"`
    B string `redis:"b"`
    C string `redis:"c"` // Unknown length of map at runtime
}

其次,您的成员是字符串,因此您无法让个人成员访问其内容,我也不认为您可以使用redigo自动执行此操作。

作为解决方法,您可以使用一些扩展字符串的类型,并且具有一种访问方法,该方法可以懒惰地将json解析为基础字典,然后返回该值。这样的事情(没有测试的写作,只是一般的想法,我不确定它会起作用,但它值得一试):

type MyString string

func (s MyString)Get(key string) (interface{}, error) {
   var m map[string]interface{}

   if err := json.Unmarshal([]byte(s), &m); err != nil {
       return nil, err
   } 

   return m[key], nil

}

它也不是很有效,因为它每次都会再次解析json。 就个人而言,我将整个模型的东西包装在一个结构中,该结构在从redigo反序列化的同时完成场景背后的所有逻辑。

答案 1 :(得分:1)

从RedisLabs查看ReJSON模块。

我为它创建了一个简单的go-client here,与Redigo一起使用。

type Model struct {
    A string `redis:"a" json:"a"`
    B string `redis:"b" json:"b"`
    C string `redis:"c" json:"c"`
}

要阅读它,请使用JSON.GET命令

v, err := redis.Bytes(rejson.JSONGet(conn, "id:123", ""))
if err != nil {
    return
}

m := new(Model)
err = json.Unmarshal(v, m)
if err != nil {
    return
}

答案 2 :(得分:0)

type Model struct {
    A string `redis:"a" json:"a"`
    B string `redis:"b" json:"b"`
    C string `redis:"c" json:"c"`
}

您可以同时使用带有redis标记的json代码。
ScanStruct应该可以正常工作,它使用redis标签。

m := Model
v, err := redis.Values(c.Do("HGETALL", key))
err = redis.ScanStruct(v, &m)