I have a JSON and want to parse the nested array using https://github.com/thedevsaddam/gojsonq
{
"total": 2,
"page": 1,
"pageSize": 50,
"data": [
{
"id": "vm-12345",
"host_id":"host-12345",
"name": "MyVirtualMachine",
"guestOS": "Windows Server 2019",
"powerState": "poweredOn",
"cpu": 2,
"memoryMB": 4096,
"disks": [
{
"id": "disk-56789",
"name": "Hard disk 1",
"capacityGB": 100,
"type": "thin"
}
],
"networks": [
{
"id": "network-98765",
"name": "VM Network",
"macAddress": "00:50:56:9A:76:5C",
"ipAddress": "192.168.1.100"
}
],
"toolsRunningStatus": "guestToolsRunning",
"connectionState": "connected"
},
{
"id": "vm-67890",
"host_id":"host-67890",
"name": "TestVM",
"guestOS": "Ubuntu 20.04",
"powerState": "poweredOff",
"cpu": 1,
"memoryMB": 2048,
"disks": [
{
"id": "disk-12345",
"name": "Hard disk 1",
"capacityGB": 50,
"type": "thick"
}
],
"networks": [
{
"id": "network-54321",
"name": "VM Network",
"macAddress": "00:50:56:9A:12:34",
"ipAddress": "192.168.1.101"
}
],
"toolsRunningStatus": "guestToolsNotRunning",
"connectionState": "disconnected"
}
]
}
as we can see here we have disks
under data
and I am using this
jq_vm.From("data").Select("id", "name", "host_id", "disks.capacityGB").Get()
to filter out but this is not returning the disks and can be seen here
[map[host_id:host-12345 id:vm-12345 name:MyVirtualMachine] map[host_id:host-67890 id:vm-67890 name:TestVM]]
can anyone help me fix this?
I think the issue here is that disks
is a list, so you can't address fields using syntax like disks.capacityGB
. You could filter it with a secondary Select
, but that wouldn't give you access to keys from the parent level.
You can include the entire disks
value in your selection:
func main() {
jq_vm := gojsonq.New().FromString(data)
selected := jq_vm.From("data").Select("id", "name", "disks")
out, _ := json.MarshalIndent(selected.Get(), "", " ")
fmt.Print(string(out))
}
Which gets you:
[
{
"disks": [
{
"capacityGB": 100,
"id": "disk-56789",
"name": "Hard disk 1",
"type": "thin"
}
],
"id": "vm-12345",
"name": "MyVirtualMachine"
},
{
"disks": [
{
"capacityGB": 50,
"id": "disk-12345",
"name": "Hard disk 1",
"type": "thick"
}
],
"id": "vm-67890",
"name": "TestVM"
}
]
It looks like there's a Go port of jq
, which would let you get what you want like this:
func main() {
query, _ := gojq.Parse(".data[]|{id: .id, name: .name, disks: [.disks[].capacityGB]}")
doc := make(map[string]interface{})
json.Unmarshal(data, &doc)
iter := query.Run(doc)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatalln(err)
}
out, _ := json.MarshalIndent(v, "", " ")
fmt.Println(string(out))
}
}
Which produces:
{
"disks": [
100
],
"id": "vm-12345",
"name": "MyVirtualMachine"
}
{
"disks": [
50
],
"id": "vm-67890",
"name": "TestVM"
}