为了账号安全,请及时绑定邮箱和手机立即绑定

使用 redigo 将 json 部分从 Redis 转换为 Go 结构

使用 redigo 将 json 部分从 Redis 转换为 Go 结构

Go
慕田峪9158850 2021-10-04 16:55:31
我有一个由浏览器发布的 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.我调用Redisv, _ := redis.Values(c.Do("HGETALL", "id:123"))我通过 redis-cli 看到正确存储的值,但将v回复转换为模型结构不起作用:var model Modelif err := redis.ScanStruct(v, &model); err != nil {    panic(err)}fmt.Printf("c %#v\n", model.C) => empty []我想访问单个 k:v 对,例如:B.y2 = 32456C[0] = "alpha@example1.com"2.我还想将 json.Marshal myJson作为 {a}、{a,b}、{a,c}、{a,b,c} 等的组合返回浏览器。我不确定如何将各种 a、b、c 字段组合组合成一个以进行编组。任何帮助,将不胜感激。
查看完整描述

3 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

首先,您应该使用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 延迟解析为底层 dict,然后返回值。像这样的东西(没有测试就写,只是一般的想法,我不确定它会起作用但值得一试):


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 反序列化的同时在幕后执行所有逻辑。


查看完整回答
反对 回复 2021-10-04
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

查看RedisLabs 的 ReJSON模块。


我在这里为它创建了一个简单的 go-client,它可以与 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

}



查看完整回答
反对 回复 2021-10-04
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

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)


查看完整回答
反对 回复 2021-10-04
  • 3 回答
  • 0 关注
  • 285 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信