golang高效JSON查询与处理插件库gojq的使用
golang高效JSON查询与处理插件库gojq的使用
简介
gojq 是一个用于在 Golang 中进行 JSON 查询的库。它主要提供以下功能:
- 使解析 JSON 配置文件更加容易
- 支持 JSON 表达式求值
- 减少类型断言解析 JSON 的痛苦
安装
go get -u github.com/elgs/gojq
从 JSON 对象查询
package main
import (
"fmt"
"github.com/elgs/gojq"
)
var jsonObj = `
{
"name": "sam",
"gender": "m",
"pet": null,
"skills": [
"Eating",
"Sleeping",
"Crawling"
],
"hello.world":true
}
`
func main() {
parser, err := gojq.NewStringQuery(jsonObj)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(parser.Query("name")) // sam <nil>
fmt.Println(parser.Query("gender")) // m <nil>
fmt.Println(parser.Query("skills.[1]")) // Sleeping <nil>
fmt.Println(parser.Query("hello")) // <nil> hello does not exist.
fmt.Println(parser.Query("pet")) // <nil> <nil>
fmt.Println(parser.Query(".")) // map[name:sam gender:m pet:<nil> skills:[Eating Sleeping Crawling] hello.world:true] <nil>
fmt.Println(parser.Query("'hello.world'")) // true <nil>
}
从 JSON 数组查询
package main
import (
"fmt"
"github.com/elgs/gojq"
)
var jsonArray = `
[
{
"name": "elgs",
"gender": "m",
"skills": [
"Golang",
"Java",
"C"
]
},
{
"name": "enny",
"gender": "f",
"skills": [
"IC",
"Electric design",
"Verification"
]
},
{
"name": "sam",
"gender": "m",
"pet": null,
"skills": [
"Eating",
"Sleeping",
"Crawling"
]
}
]
`
func main() {
parser, err := gojq.NewStringQuery(jsonArray)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(parser.Query("[0].name")) // elgs <nil>
fmt.Println(parser.Query("[1].gender")) // f <nil>
fmt.Println(parser.Query("[2].skills.[1]")) // Sleeping <nil>
fmt.Println(parser.Query("[2].hello")) // <nil> hello does not exist.
fmt.Println(parser.Query("[2].pet")) // <nil> <nil>
}
嵌套查询
package main
import (
"fmt"
"github.com/elgs/gojq"
)
var jsonArray = `
[
{
"name": "elgs",
"gender": "m",
"skills": [
"Golang",
"Java",
"C"
]
},
{
"name": "enny",
"gender": "f",
"skills": [
"IC",
"Electric design",
"Verification"
]
},
{
"name": "sam",
"gender": "m",
"pet": null,
"skills": [
"Eating",
"Sleeping",
"Crawling"
]
}
]
`
func main() {
parser, err := gojq.NewStringQuery(jsonArray)
if err != nil {
fmt.Println(err)
return
}
samSkills, err := parser.Query("[2].skills")
fmt.Println(samSkills, err) //[Eating Sleeping Crawling] <nil>
samSkillParser := gojq.NewQuery(samSkills)
fmt.Println(samSkillParser.Query("[1]")) //Sleeping <nil>
}
通过以上示例可以看到,gojq 提供了简单直观的方式来查询和操作 JSON 数据,无论是对象还是数组,甚至是嵌套结构,都能轻松处理。
更多关于golang高效JSON查询与处理插件库gojq的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高效JSON查询与处理插件库gojq的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Gojq: 高效的Golang JSON查询与处理库
gojq是一个纯Go实现的jq兼容JSON查询和处理库,它提供了强大的JSON数据查询和转换能力,同时保持了高性能和低内存消耗。
安装
go get github.com/itchyny/gojq
基本使用
1. 简单查询
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/itchyny/gojq"
)
func main() {
query, err := gojq.Parse(".name")
if err != nil {
log.Fatalln(err)
}
input := map[string]interface{}{"name": "Alice", "age": 30}
iter := query.Run(input)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatalln(err)
}
fmt.Printf("%#v\n", v) // 输出: "Alice"
}
}
2. 复杂查询
func complexQuery() {
jsonStr := `{
"users": [
{"id": 1, "name": "Alice", "roles": ["admin", "user"]},
{"id": 2, "name": "Bob", "roles": ["user"]},
{"id": 3, "name": "Charlie", "roles": ["user", "editor"]}
]
}`
var input interface{}
if err := json.Unmarshal([]byte(jsonStr), &input); err != nil {
log.Fatal(err)
}
query, err := gojq.Parse(".users[] | select(.roles[] | contains(\"admin\")) | .name")
if err != nil {
log.Fatal(err)
}
iter := query.Run(input)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatal(err)
}
fmt.Println(v) // 输出: "Alice"
}
}
高级特性
1. 自定义函数
func customFunction() {
query, err := gojq.Parse(`
def to_upper: ascii_upcase;
.users[].name | to_upper
`)
if err != nil {
log.Fatal(err)
}
input := map[string]interface{}{
"users": []interface{}{
map[string]interface{}{"name": "Alice"},
map[string]interface{}{"name": "Bob"},
},
}
iter := query.Run(input)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatal(err)
}
fmt.Println(v) // 输出: "ALICE" 然后 "BOB"
}
}
2. 多步骤数据处理
func multiStageProcessing() {
jsonStr := `{
"products": [
{"id": 1, "name": "Laptop", "price": 999.99, "stock": 5},
{"id": 2, "name": "Mouse", "price": 19.99, "stock": 42},
{"id": 3, "name": "Keyboard", "price": 49.99, "stock": 12}
]
}`
var input interface{}
if err := json.Unmarshal([]byte(jsonStr), &input); err != nil {
log.Fatal(err)
}
query, err := gojq.Parse(`
.products[]
| select(.price < 50)
| {name, total_value: (.price * .stock)}
| select(.total_value > 200)
`)
if err != nil {
log.Fatal(err)
}
iter := query.Run(input)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatal(err)
}
fmt.Printf("%+v\n", v)
// 输出: map[name:Mouse total_value:839.58]
// map[name:Keyboard total_value:599.88]
}
}
性能优化技巧
- 预编译查询:对于重复使用的查询,先Parse然后复用Query对象
- 使用迭代器:直接处理迭代器结果而不是收集到数组中
- 合理使用流式处理:对于大JSON文件,考虑结合json.Decoder使用
func performanceOptimization() {
// 预编译查询
query, err := gojq.Parse(".items[].id")
if err != nil {
log.Fatal(err)
}
// 大文件流式处理
file, err := os.Open("large.json")
if err != nil {
log.Fatal(err)
}
defer file.Close()
dec := json.NewDecoder(file)
for {
var data interface{}
if err := dec.Decode(&data); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
iter := query.Run(data)
for {
v, ok := iter.Next()
if !ok {
break
}
if err, ok := v.(error); ok {
log.Fatal(err)
}
// 处理结果
fmt.Println(v)
}
}
}
与标准库对比
gojq相比标准库的json包提供了更强大的查询能力:
- 复杂查询:可以轻松实现嵌套查询、过滤、映射等
- 数据转换:支持复杂的数据格式转换
- 更简洁:使用类似jq的DSL语法,代码更简洁
总结
gojq是Golang中处理JSON数据的强大工具,特别适合需要复杂查询和转换的场景。它兼容jq语法,学习曲线平缓,性能优异,是标准库json包的有力补充。