You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JSON Slice is a Go package which allows to execute fast jsonpath queries without unmarshalling the whole data.
Sometimes you need to get a single value from incoming json using jsonpath, for example to route data accordingly or so. To do that you must unmarshall the whole data into interface{} struct and then apply some jsonpath library to it, only to get just a tiny little value. What a waste of resourses! Well, now there's jsonslice.
Simply call jsonslice.Get on your raw json data to slice out just the part you need. The []byte received can then be unmarshalled into a struct or used as it is.
$.obj.length() -- number of elements in an array or string length, depending on the obj type $.obj.count() -- same as above $.val.size() -- value size in bytes (as is)
Slices
$.arr[start:end:step] $.arr[start:end]
Selects elements from start (inclusive) to end (exclusive), stepping by step. If step is omitted or zero, then 1 is implied. Out-of-bounds values are reduced to the nearest bound.
If step is positive:
empty start treated as the first element inclusive
empty end treated as the last element inclusive
start should be less then end, otherwise result will be empty
If step is negative:
empty start treated as last element inclusive
empty end treated as the first element inclusive
start should be greater then end, otherwise result will be empty
Filters
[?()] -- filter expression. Applicable to arrays only @ -- the root of the current element of the array. Used only within a filter. @.val -- a field of the current element of the array.
Abstract equality (mimics JavaScript). Examples: true=="1", 42=="42". Use single or double quotes for string expressions. [?(@.color=='red')] or [?(@.color=="red")]
!=
Abstract not equal to [?(@.author != "Herman Melville")]
!==
Strict not equal to ?(@.tag !== "1")
>
Greater than [?(@.price > 10)]
>=
Greater than or equal to
<
Less than
<=
Less than or equal to
=~
Match a regexp [?(@.name =~ /sword.*/i]
!~ or !=~
Don't match a regexp [?(@.name !~ /sword.*/i]
&&
Logical AND [?(@.price < 10 && @isbn)]
||
Logical OR [?(@.price > 10 || @.category == 'reference')]
!
Logical NOT [?(!@.is_expensive)]
|
Bitwise OR [?(@.bits|@.pieces > 0)]
&
Bitwise AND [?(@.bits & 7 == 1)]
^
Bitwise XOR [?(@.bits ^ 1 > 0)]
~
Bitwise NOT [?(~@.bits == 0xF0)]
<<
Bitwise left shift [?(@.bits << 1 == 2)]
>>
Bitwise right shift [?(@.bits >> 1 == 0)]
Comparison details
Comparison mostly complies with JavaScript specifications, see Testing and Comparison Operations.
If you encounter wrong or inconsistent comparison behaviour please let me know by creating an issue in this repository.
Examples
Assuming sample0.json and sample1.json in the example directory:
Much more examples can be found in jsonslice_test.go
Benchmarks (Core i9-9880H)
$ go test -bench=. -benchmem -benchtime=4s goos: darwin goarch: amd64 pkg: github.com/bhmj/jsonslice cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz ++ standard json.Unmarshal (for reference): Benchmark_Unmarshal-16 398998 11268 ns/op 4272 B/op 130 allocs/op ++ and here's a jsonslice.Get: Benchmark_Jsonslice_Get_Simple-16 1660604 2885 ns/op 24 B/op 1 allocs/op ++ parsing is the first part of jsonslicing, here it is separately: Benchmark_JsonSlice_ParsePath-16 11955015 400 ns/op 0 B/op 0 allocs/op ++ aggregating non-contiguous elements may take a bit longer (extra mallocs involved): Benchmark_Jsonslice_Get_Aggregated-16 1000000 4335 ns/op 313 B/op 10 allocs/op ++ standard json.Unmarshal of a large json (10 Mb): Benchmark_Unmarshal_10Mb-16 100 40787414 ns/op 224 B/op 5 allocs/op ++ jsonslicing the same json, target element is at the start: Benchmark_Jsonslice_Get_10Mb_First-16 3459492 1370 ns/op 24 B/op 1 allocs/op ++ jsonslicing the same json, target element is at the end: still beats Unmarshal Benchmark_Jsonslice_Get_10Mb_Last-16 133 35731931 ns/op 54 B/op 1 allocs/op PASS ok github.com/bhmj/jsonslice 52.452s
Changelog
1.1.3 (2024-07-29) -- bugfix: space after closing } of a target object.
1.1.2 (2022-01-02) -- Unicode support added. Expression parser upgrade to v0.9.1
Bugfix: indexing of array element inside expression (@[2]).
Bugfix: ecaped backslash in node key now works ($.["\\"]).
See Test_Fixes function for bugfix details.
1.1.1 (2021-10-20) -- Expression parser upgrade to v0.9.0
1.1.0 (2021-11-12) -- Expression parser/evaluator has been separated to different project and completely rewritten. Parentheses now fully supported. Exponentiation operator added (**). Bitwise operators added (|, &, ^, <<, >>). All expression calculations are JavaScript-compliant.
1.0.6 (2021-10-31) -- JS-like behaviour on string/number/boolean values comparison. === operator added for strict comparison. Strings are now comparable.
1.0.5 (2020-09-22) -- bugfix: $..many.keys used to trigger on many without recursing deeper on keys.