繁体   English   中英

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

[英]Casting json parts into Go structs from Redis using 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回复转换为Model结构不起作用:

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场组合组合成一个被编组的组合。

任何帮助,将不胜感激。

首先,你应该用redis而不是json标签来标记你的字段名称,这就是redigo用于ScanStruct()的内容。 例如

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反序列化的同时完成场景背后的所有逻辑。

查看RedisLabs的ReJSON模块。

我在这里为Redigo创建了一个简单的go-client。

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
}
type Model struct {
    A string `redis:"a" json:"a"`
    B string `redis:"b" json:"b"`
    C string `redis:"c" json:"c"`
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM