1# GJSON Path Syntax
2
3A GJSON Path is a text string syntax that describes a search pattern for quickly retrieving values from a JSON payload.
4
5This document is designed to explain the structure of a GJSON Path through examples.
6
7- [Path structure](#path-structure)
8- [Basic](#basic)
9- [Wildcards](#wildcards)
10- [Escape Character](#escape-character)
11- [Arrays](#arrays)
12- [Queries](#queries)
13- [Dot vs Pipe](#dot-vs-pipe)
14- [Modifiers](#modifiers)
15- [Multipaths](#multipaths)
16- [Literals](#literals)
17
18The definitive implementation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson).
19Use the [GJSON Playground](https://gjson.dev) to experiment with the syntax online.
20
21## Path structure
22
23A GJSON Path is intended to be easily expressed as a series of components separated by a `.` character.
24
25Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, `!`, and `?`.
26
27## Example
28
29Given this JSON
30
31```json
32{
33 "name": {"first": "Tom", "last": "Anderson"},
34 "age":37,
35 "children": ["Sara","Alex","Jack"],
36 "fav.movie": "Deer Hunter",
37 "friends": [
38 {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
39 {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
40 {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
41 ]
42}
43```
44
45The following GJSON Paths evaluate to the accompanying values.
46
47### Basic
48
49In many cases you'll just want to retrieve values by object name or array index.
50
51```go
52name.last "Anderson"
53name.first "Tom"
54age 37
55children ["Sara","Alex","Jack"]
56children.0 "Sara"
57children.1 "Alex"
58friends.1 {"first": "Roger", "last": "Craig", "age": 68}
59friends.1.first "Roger"
60```
61
62### Wildcards
63
64A key may contain the special wildcard characters `*` and `?`.
65The `*` will match on any zero+ characters, and `?` matches on any one character.
66
67```go
68child*.2 "Jack"
69c?ildren.0 "Sara"
70```
71
72### Escape character
73
74Special purpose characters, such as `.`, `*`, and `?` can be escaped with `\`.
75
76```go
77fav\.movie "Deer Hunter"
78```
79
80You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in your source code.
81
82```go
83// Go
84val := gjson.Get(json, "fav\\.movie") // must escape the slash
85val := gjson.Get(json, `fav\.movie`) // no need to escape the slash
86```
87
88```rust
89// Rust
90let val = gjson::get(json, "fav\\.movie") // must escape the slash
91let val = gjson::get(json, r#"fav\.movie"#) // no need to escape the slash
92```
93
94
95### Arrays
96
97The `#` character allows for digging into JSON Arrays.
98
99To get the length of an array you'll just use the `#` all by itself.
100
101```go
102friends.# 3
103friends.#.age [44,68,47]
104```
105
106### Queries
107
108You can also query an array for the first match by using `#(...)`, or find all matches with `#(...)#`.
109Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators,
110and the simple pattern matching `%` (like) and `!%` (not like) operators.
111
112```go
113friends.#(last=="Murphy").first "Dale"
114friends.#(last=="Murphy")#.first ["Dale","Jane"]
115friends.#(age>45)#.last ["Craig","Murphy"]
116friends.#(first%"D*").last "Murphy"
117friends.#(first!%"D*").last "Craig"
118```
119
120To query for a non-object value in an array, you can forgo the string to the right of the operator.
121
122```go
123children.#(!%"*a*") "Alex"
124children.#(%"*a*")# ["Sara","Jack"]
125```
126
127Nested queries are allowed.
128
129```go
130friends.#(nets.#(=="fb"))#.first >> ["Dale","Roger"]
131```
132
133*Please note that prior to v1.3.0, queries used the `#[...]` brackets. This was
134changed in v1.3.0 as to avoid confusion with the new [multipath](#multipaths)
135syntax. For backwards compatibility, `#[...]` will continue to work until the
136next major release.*
137
138The `~` (tilde) operator will convert a value to a boolean before comparison.
139
140Supported tilde comparison type are:
141
142```
143~true Converts true-ish values to true
144~false Converts false-ish and non-existent values to true
145~null Converts null and non-existent values to true
146~* Converts any existing value to true
147```
148
149For example, using the following JSON:
150
151```json
152{
153 "vals": [
154 { "a": 1, "b": "data" },
155 { "a": 2, "b": true },
156 { "a": 3, "b": false },
157 { "a": 4, "b": "0" },
158 { "a": 5, "b": 0 },
159 { "a": 6, "b": "1" },
160 { "a": 7, "b": 1 },
161 { "a": 8, "b": "true" },
162 { "a": 9, "b": false },
163 { "a": 10, "b": null },
164 { "a": 11 }
165 ]
166}
167```
168
169To query for all true-ish or false-ish values:
170
171```
172vals.#(b==~true)#.a >> [2,6,7,8]
173vals.#(b==~false)#.a >> [3,4,5,9,10,11]
174```
175
176The last value which was non-existent is treated as `false`
177
178To query for null and explicit value existence:
179
180```
181vals.#(b==~null)#.a >> [10,11]
182vals.#(b==~*)#.a >> [1,2,3,4,5,6,7,8,9,10]
183vals.#(b!=~*)#.a >> [11]
184```
185
186### Dot vs Pipe
187
188The `.` is standard separator, but it's also possible to use a `|`.
189In most cases they both end up returning the same results.
190The cases where`|` differs from `.` is when it's used after the `#` for [Arrays](#arrays) and [Queries](#queries).
191
192Here are some examples
193
194```go
195friends.0.first "Dale"
196friends|0.first "Dale"
197friends.0|first "Dale"
198friends|0|first "Dale"
199friends|# 3
200friends.# 3
201friends.#(last="Murphy")# [{"first": "Dale", "last": "Murphy", "age": 44},{"first": "Jane", "last": "Murphy", "age": 47}]
202friends.#(last="Murphy")#.first ["Dale","Jane"]
203friends.#(last="Murphy")#|first <non-existent>
204friends.#(last="Murphy")#.0 []
205friends.#(last="Murphy")#|0 {"first": "Dale", "last": "Murphy", "age": 44}
206friends.#(last="Murphy")#.# []
207friends.#(last="Murphy")#|# 2
208```
209
210Let's break down a few of these.
211
212The path `friends.#(last="Murphy")#` all by itself results in
213
214```json
215[{"first": "Dale", "last": "Murphy", "age": 44},{"first": "Jane", "last": "Murphy", "age": 47}]
216```
217
218The `.first` suffix will process the `first` path on each array element *before* returning the results. Which becomes
219
220```json
221["Dale","Jane"]
222```
223
224But the `|first` suffix actually processes the `first` path *after* the previous result.
225Since the previous result is an array, not an object, it's not possible to process
226because `first` does not exist.
227
228Yet, `|0` suffix returns
229
230```json
231{"first": "Dale", "last": "Murphy", "age": 44}
232```
233
234Because `0` is the first index of the previous result.
235
236### Modifiers
237
238A modifier is a path component that performs custom processing on the JSON.
239
240For example, using the built-in `@reverse` modifier on the above JSON payload will reverse the `children` array:
241
242```go
243children.@reverse ["Jack","Alex","Sara"]
244children.@reverse.0 "Jack"
245```
246
247There are currently the following built-in modifiers:
248
249- `@reverse`: Reverse an array or the members of an object.
250- `@ugly`: Remove all whitespace from JSON.
251- `@pretty`: Make the JSON more human readable.
252- `@this`: Returns the current element. It can be used to retrieve the root element.
253- `@valid`: Ensure the json document is valid.
254- `@flatten`: Flattens an array.
255- `@join`: Joins multiple objects into a single object.
256- `@keys`: Returns an array of keys for an object.
257- `@values`: Returns an array of values for an object.
258- `@tostr`: Converts json to a string. Wraps a json string.
259- `@fromstr`: Converts a string from json. Unwraps a json string.
260- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db).
261- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf).
262
263#### Modifier arguments
264
265A modifier may accept an optional argument. The argument can be a valid JSON payload or just characters.
266
267For example, the `@pretty` modifier takes a json object as its argument.
268
269```
270@pretty:{"sortKeys":true}
271```
272
273Which makes the json pretty and orders all of its keys.
274
275```json
276{
277 "age":37,
278 "children": ["Sara","Alex","Jack"],
279 "fav.movie": "Deer Hunter",
280 "friends": [
281 {"age": 44, "first": "Dale", "last": "Murphy"},
282 {"age": 68, "first": "Roger", "last": "Craig"},
283 {"age": 47, "first": "Jane", "last": "Murphy"}
284 ],
285 "name": {"first": "Tom", "last": "Anderson"}
286}
287```
288
289*The full list of `@pretty` options are `sortKeys`, `indent`, `prefix`, and `width`.
290Please see [Pretty Options](https://github.com/tidwall/pretty#customized-output) for more information.*
291
292#### Custom modifiers
293
294You can also add custom modifiers.
295
296For example, here we create a modifier which makes the entire JSON payload upper or lower case.
297
298```go
299gjson.AddModifier("case", func(json, arg string) string {
300 if arg == "upper" {
301 return strings.ToUpper(json)
302 }
303 if arg == "lower" {
304 return strings.ToLower(json)
305 }
306 return json
307})
308"children.@case:upper" ["SARA","ALEX","JACK"]
309"children.@case:lower.@reverse" ["jack","alex","sara"]
310```
311
312*Note: Custom modifiers are not yet available in the Rust version*
313
314### Multipaths
315
316Starting with v1.3.0, GJSON added the ability to join multiple paths together
317to form new documents. Wrapping comma-separated paths between `[...]` or
318`{...}` will result in a new array or object, respectively.
319
320For example, using the given multipath:
321
322```
323{name.first,age,"the_murphys":friends.#(last="Murphy")#.first}
324```
325
326Here we selected the first name, age, and the first name for friends with the
327last name "Murphy".
328
329You'll notice that an optional key can be provided, in this case
330"the_murphys", to force assign a key to a value. Otherwise, the name of the
331actual field will be used, in this case "first". If a name cannot be
332determined, then "_" is used.
333
334This results in
335
336```json
337{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]}
338```
339
340### Literals
341
342Starting with v1.12.0, GJSON added support of json literals, which provides a way for constructing static blocks of json. This is can be particularly useful when constructing a new json document using [multipaths](#multipaths).
343
344A json literal begins with the '!' declaration character.
345
346For example, using the given multipath:
347
348```
349{name.first,age,"company":!"Happysoft","employed":!true}
350```
351
352Here we selected the first name and age. Then add two new fields, "company" and "employed".
353
354This results in
355
356```json
357{"first":"Tom","age":37,"company":"Happysoft","employed":true}
358```
359
360*See issue [#249](https://github.com/tidwall/gjson/issues/249) for additional context on JSON Literals.*