Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Use GJSON in TB codes #312

Open
jihoon-seo opened this issue Nov 11, 2020 · 5 comments
Open

Suggestion: Use GJSON in TB codes #312

jihoon-seo opened this issue Nov 11, 2020 · 5 comments
Labels
feature request Issue related with new feature

Comments

@jihoon-seo
Copy link
Member

Found by @seokho-son

https://github.com/tidwall/gjson

GJSON is a Go package that provides a fast and simple way to get values from a json document. It has features such as one line retrieval, dot notation paths, iteration, and parsing json lines.

Also check out SJSON for modifying json, and the JJ command line tool.

@issue-label-bot
Copy link

Issue-Label Bot is automatically applying the label feature_request to this issue, with a confidence of 0.97. Please mark this comment with 👍 or 👎 to give our bot feedback!

Links: app homepage, dashboard and code for this bot.

@issue-label-bot issue-label-bot bot added the feature request Issue related with new feature label Nov 11, 2020
@seokho-son
Copy link
Member

@jihoon-seo 전체적으로 적용하는 것이 좋을까요?

일단 저는 CB-DF 의 모니터링 데이터 조회를 위해서 활용해보았습니다~
일부 파라미터만 필요하기 때문에, 전체 structure 가 필요 없을 것 같아서, gjson 을 적용해 보았어요.. ^^

result := string(body)
switch {
case metric == MonMetricCpu:
value := gjson.Get(string(body), "values.cpu_utilization")
result = value.String()
case metric == MonMetricMem:
value := gjson.Get(string(body), "values.mem_utilization")
result = value.String()
case metric == MonMetricDisk:
value := gjson.Get(string(body), "values.disk_utilization")
result = value.String()
case metric == MonMetricNet:
value := gjson.Get(string(body), "values.bytes_out")
result = value.String()
default:
}

@jihoon-seo
Copy link
Member Author

@jihoon-seo
Copy link
Member Author

Spider 가 제공한 & TB가 저장하고 있는 KeyValueList 에서 정보를 추출할 때 유용할 것 같은 패키지들이 있네요 ㅎㅎ

일단 얘가 눈에 띕니다.
https://github.com/Jeffail/gabs

jsonParsed, err := gabs.ParseJSON([]byte(`{
	"outter":{
		"inner":{
			"value1":10,
			"value2":22
		},
		"alsoInner":{
			"value1":20,
			"array1":[
				30, 40
			]
		}
	}
}`))
if err != nil {
	panic(err)
}

var value float64
var ok bool

value, ok = jsonParsed.Path("outter.inner.value1").Data().(float64)
// value == 10.0, ok == true

value, ok = jsonParsed.Search("outter", "inner", "value1").Data().(float64)
// value == 10.0, ok == true

value, ok = jsonParsed.Search("outter", "alsoInner", "array1", "1").Data().(float64)
// value == 40.0, ok == true

gObj, err := jsonParsed.JSONPointer("/outter/alsoInner/array1/1")
if err != nil {
	panic(err)
}
value, ok = gObj.Data().(float64)
// value == 40.0, ok == true

value, ok = jsonParsed.Path("does.not.exist").Data().(float64)
// value == 0.0, ok == false

exists := jsonParsed.Exists("outter", "inner", "value1")
// exists == true

exists = jsonParsed.ExistsP("does.not.exist")
// exists == false

얘도 눈에 띕니다.
https://github.com/buger/jsonparser

data := []byte(`{
  "person": {
    "name": {
      "first": "Leonid",
      "last": "Bugaev",
      "fullName": "Leonid Bugaev"
    },
    "github": {
      "handle": "buger",
      "followers": 109
    },
    "avatars": [
      { "url": "https://avatars1.githubusercontent.com/u/14009?v=3&s=460", "type": "thumbnail" }
    ]
  },
  "company": {
    "name": "Acme"
  }
}`)

// You can specify key path by providing arguments to Get function
jsonparser.Get(data, "person", "name", "fullName")

// There is `GetInt` and `GetBoolean` helpers if you exactly know key data type
jsonparser.GetInt(data, "person", "github", "followers")

// When you try to get object, it will return you []byte slice pointer to data containing it
// In `company` it will be `{"name": "Acme"}`
jsonparser.Get(data, "company")

근데 이 정도는 GJSON 도 비슷하게 가능할 것 같기도 하네요 🤔

@yunkon-kim
Copy link
Member

yunkon-kim commented Feb 9, 2022

Iteration을 고려하신다면 GJSON이 좋을 것 같다는 의견을 드립니다 😄

JSON 데이터 구조에 집중할 수 있고, 몇 줄로 원하는 데이터(string, array, object 등)를 파싱하기 용이해서 입니다.

참고: gabs, jsonparser, gjson모두 foreach 형식의 Interation을 지원하고요. 이를 사용한다면 함수 및 매개변수의 이해, Iteration 내에서 Iteration 수행등의 불편함을 조금 극복해야 합니다. 😅

gjson예시

Suppose you want all the last names from the following json:

{
  "programmers": [
    {
      "firstName": "Janet", 
      "lastName": "McLaughlin", 
    }, {
      "firstName": "Elliotte", 
      "lastName": "Hunter", 
    }, {
      "firstName": "Jason", 
      "lastName": "Harold", 
    }
  ]
}

You would use the path "programmers.#.lastName" like such:

result := gjson.Get(json, "programmers.#.lastName")
for _, name := range result.Array() {
	println(name.String())
}

You can also query an object inside an array:

name := gjson.Get(json, `programmers.#(lastName="Hunter").firstName`)
println(name.String())  // prints "Elliotte"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issue related with new feature
Projects
None yet
Development

No branches or pull requests

3 participants