I am using a key value store as the backend for my golang application, with the date serving as the key (to keep entries sorted) and json documents as the values. The top level namespace of the json (foo
) and the type
and date
are present in each json document that I'm storing but otherwise there are some differences (especially with respect to some nested json data), so when keyI'm pulling from the database, I don't really know what I'm pulling out at any time that I'm looping through . Here is a sample of the json data
{
"foo": {
"id": "124",
"type": "baz",
"rawdata": [
123,
345,
345
],
"epoch": "1433120656704"
}
}
{
"foo": {
"id": "234",
"type": "bar",
"rawdata": [
{
"key": "dog",
"values": [
123,
234
]
},
{
"key": "cat",
"values": [
23,
45
]
}
],
"epoch": "1433120656705"
}
}
when I'm pulling from the database, the first thing I do is unmarshal each entry into a map[string]*json.RawMessage
to deal with the foo
namespace
//as I'm looping through the entries in the database
var objmap map[string]*json.RawMessage
if err := json.Unmarshal(dbvalue, &objmap); err !=nil{
return err
}
which I do thanks to this SO answer
However, unlike in that SO answer, when I have to unmarshal again whatever is contained under the foo
namespace I don't know which struct to unmarshal into
if err :=json.Unmarshal(*objmap["foo"], &bazorbar; err != nil{
return err
}
type Baz struct{
Id string `json:"id"`
Type string `json:"type"`
RawData []int `json:"rawdata"`
Epoch string `json:"epoch"`
}
type Bar struct{
Id string `json:"id"`
Type string `json:"type"`
RawData []*Qux `json:"rawdata"`
Epoch string `json:"epoch"`
}
//nested inside Bar
type Qux struct{
Key string `json:"key"`
Values []int `json:"values`
}
Two part Question:
Update: the initial answer provided by @chendesheng enables me to find out the type but not to unmarshal again into a struct once that type has been determined (which I need to do), so based on a conversation in the comments to his/her answer, I would be interested in either of these possibilities
a) make a copy of the json.RawMessage, unmarshal into the interface as you shown (by chendesheng's answer), and then unmarshal the copy itno the struct once you know the type (from having unmarshaled into the interface)?
b) use a regular expression to determine the type and then unmarshal into a struct of that type once it's known
Two ways to check struct type:
http://play.golang.org/p/gfP6P4SmaC
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With