JSON guide · 4 min read
JSONPath Examples: Query Nested JSON Step by Step
Learn JSONPath with a realistic dataset, from simple property selection and arrays to wildcards, recursive descent and filters.
Use one dataset for the examples
Learning is easier when each expression runs against the same data. This sample includes nested objects, an array, numeric values and an optional field so the later queries have realistic edge cases.
{
"store": {
"books": [
{"id":1,"title":"Dune","price":16,"inStock":true},
{"id":2,"title":"Sapiens","price":12,"inStock":false},
{"id":3,"title":"Clean Code","price":18}
],
"location": {"city":"Kolkata"}
}
}Start at the root and select properties
The dollar sign represents the document root. Dot notation selects object properties, while bracket notation is useful for array indexes and unusual property names.
$.store.location.city
Result: "Kolkata"
$.store.books[0].title
Result: "Dune"Use wildcards for every item at one level
The wildcard selects all members at the current level. Applied to the books array, it extracts the title from every element without naming indexes individually.
$.store.books[*].title
Results:
"Dune"
"Sapiens"
"Clean Code"Filter array items by a condition
Filters select elements that satisfy an expression. The current candidate is commonly referenced with @. Historical implementations vary in filter syntax, so test expressions with the same library your application uses.
$.store.books[?(@.price < 15)].title
Result: "Sapiens"
$.store.books[?(@.inStock == true)].title
Result: "Dune"Use recursive descent carefully
Recursive descent searches through descendants instead of following one fixed hierarchy. It is useful for exploration, but broad expressions can match unrelated fields when the same property name appears in several branches.
$..price
Results:
16
12
18Test missing fields and multiple matches
The third book has no inStock property. Real responses often contain optional fields, nulls and historical variations. A query returning nothing can mean the field is absent, the filter did not match or the path is wrong.
Wildcards, filters and recursive descent may return several matches. Consumer code should not assume a scalar when the expression naturally returns a collection.
Build queries one segment at a time
Paste representative data into JSONPath Tester, start with a broad branch and add one segment at a time. Keep edge cases in the sample so brittle queries fail during development rather than in production.
- Verify the top-level branch first.
- Add one property or array segment at a time.
- Inspect exact matches after every change.
- Test missing fields and empty arrays.
- Confirm production-library syntax for filters and extensions.
Use bracket notation for awkward property names
Dot notation is convenient when a property name is simple. Bracket notation is safer when a key contains spaces, punctuation or characters that could otherwise be interpreted as JSONPath syntax. It also makes the distinction between a property name and an array index explicit.
{
"build.info": {
"release name": "2026.08"
}
}
$['build.info']['release name']
Result: "2026.08"Test cardinality as well as values
A query can return zero, one or many matches depending on the payload. Production code should decide what each cardinality means instead of assuming that a path which returned one value in a sample will always behave like a scalar lookup.
For example, a wildcard over an array naturally returns a collection. A filter may return an empty collection when no record matches. Recursive descent can unexpectedly return several values when the same key appears in unrelated branches. Include those cases in tests when the query drives application logic.
Prefer standard JSONPath when portability matters
JSONPath is now standardized in RFC 9535, but many libraries existed before the standard and still expose extensions or historical filter syntax. If an expression must run in several languages or products, keep to the standardized selectors where possible and verify behavior in each implementation.
JSON Hearth uses JSONPath-Plus for its tester, so expressions accepted by the browser tool should still be checked against the exact JSONPath implementation used by your production application before being promoted into code or configuration.
Primary sources
References and specifications
- RFC 9535 — JSONPath: Query Expressions for JSON
The IETF standard defining JSONPath syntax and semantics.
- JSONPath-Plus documentation
Documentation for the JSONPath implementation used by JSON Hearth's tester.
Common questions
Frequently asked questions
Is JSONPath one universal standard?
JSONPath now has an IETF standard, but older libraries still differ in extensions and filter behavior. Test with your actual implementation.
What does $ mean in JSONPath?
It represents the root of the JSON document and is the starting point for an absolute JSONPath expression.
What is the difference between a wildcard and recursive descent?
A wildcard selects children at one level; recursive descent searches through descendants below the current location.
Why does my filter work on one sample but not another?
The other payload may have missing properties, different types or empty arrays. Test representative variants rather than a single happy-path sample.