I'm having issues querying over this json
{
"cars":{
"dfhuidsfiusd":{
"name":"Mercedes",
details: {
"plate_number":"sas2-hd-3",
"year": 2009
}
},
"uiwouiouss":{
"name":"Jaguar",
details: {
"plate_number":"sas2-hd-3",
"year": 2009
},
},
"sdikdshkjsd":{
"name":"Toyota",
details: {
"plate_number":"sas2-hd-3",
"year": 2009
}
}
}
}
To get elements in the details object i need to pass through these random values which could change.
I decided to go with this library https://github.com/tidwall/gjson code :
result := gjson.Get(json, `cars.#.details(year="2009")`)
println(result.String())
Since they all value year=2009 in common, I am expecting the following output:
dfhuidsfiusd
sdikdshkjsd
uiwouiouss
But it's just prints empty
Putting these random values in an array and iterating might work, but I want to assume these values are not known beforehand, thanks.
CodePudding user response:
I read the documentation a bit, hope this helps:
package main
import (
"github.com/tidwall/gjson"
)
func main() {
json := `{
"cars":{
"dfhuidsfiusd":{
"name":"Mercedes",
"details": {
"plate_number":"sas2-hd-3",
"year": 2010
}
},
"uiwouiouss":{
"name":"Jaguar",
"details": {
"plate_number":"sas2-hd-3",
"year": 2010
},
},
"sdikdshkjsd":{
"name":"Toyota",
"details": {
"plate_number":"sas2-hd-3",
"year": 2012
}
}
}
}`
result := gjson.Get(json, `cars.@values.#(details.year=2010)#.name`)
println(result.String())
}
CodePudding user response:
I think it is not possible to get items' names by just using #
or *
. You have to iterate over those items manually:
gjson.Get(json, "cars").ForEach(func(path, value gjson.Result) bool {
value.ForEach(func(method, value gjson.Result) bool {
y := value.Get("year")
if y.Int() == 2009 {
fmt.Println(path)
}
return true
})
return true
})
CodePudding user response:
You can use the standard encoding/json package instead of adding an external dependency.
Unmarshal the JSON to a Go type matching the structure of the JSON. A Go map corresponds to a JSON object with unknown field names. Iterate through the result.
var v struct {
Cars map[string]struct {
Name string
Details struct {
Plate_Number string
Year int
}
}
}
if err := json.Unmarshal(data, &v); err != nil {
log.Fatal(err)
}
for k, car := range v.Cars {
fmt.Println(k, car.Name, car.Details.Plate_Number, car.Details.Year)
}
The output of this program is:
uiwouiouss Jaguar sas2-hd-3 2009
sdikdshkjsd Toyota sas2-hd-3 2009
dfhuidsfiusd Mercedes sas2-hd-3 2009
Run the code here.
Use this code to collect the object keys where the year is 2009:
var keys []string
for k, car := range v.Cars {
if car.Details.Year == 2009 {
keys = append(keys, k)
}
}