I am getting a jsonb column from postgres which has value something like
{
"a": 123,
"b": "some str",
"c": {"d": 23},
"e": {"f":34, "g", 434}
}
How can i access keys a, b, d, f, g? Thanks
EDIT: getting the jsonb column "vars":
type Msg struct{
Id int
Vars map[string]interface{}
}
queryToGetD := "select id, vars from msg_table"
if rows, errRow := db.Query(queryToGetD); errRow != nil {
return nil, fmt.Errorf("error while getting data \nquery %s \nerror %s", queryToGetD, err)
} else {
func (){
defer rows.Close()
for rows.Next(){
var msg Msg
var vars string
if err := rows.Scan(&msg.Id, &vars); err != nil{
// handle error
continue
}else{
if err := json.Unmarshal([]byte(vars), &msg.Vars); err != nil {
// handle error
continue
}
// Add msg to the needed slice
}
}
}
}
CodePudding user response:
For a and b you can do msg.Vars["a"] and msg.Vars["b"] respectively to access those values. For d, f, and g you need to first access their parents just like you would access a and b. Then you need to type-assert the result of that access to the map[string]interface{} type and then access the desired fields through the result of the type assertion.
fmt.Println(msg.Vars["a"]) // access a
fmt.Println(msg.Vars["b"]) // access b
c := msg.Vars["c"].(map[string]interface{}) // access c and type-assert as map[string]interface{}
fmt.Println(c["d"]) // then access d
https://go.dev/play/p/oZERUsL2EUY
Or use a struct that matches the json, then you can access the fields with the selector expression
type Vars struct {
A int `json:"a"`
B string `json:"b"`
C struct {
D int `json:"d"`
} `json:"c"`
E struct {
F int `json:"f"`
G int `json:"g"`
} `json:"e"`
}
// ...
fmt.Println(msg.Vars.A)
fmt.Println(msg.Vars.B)
fmt.Println(msg.Vars.C.D)
fmt.Println(msg.Vars.E.F)
fmt.Println(msg.Vars.E.G)
