$.store.book[[email protected] < 10].title is the JSONPath for the titles of the books under 10. In jq it’s .store.book[] | select(.price < 10) | .title, and in JMESPath it’s store.book[?price < `10`].title. All three answer Sayings of the Century and Moby Dick on the RFC 9535 bookstore, the document in the tester below.
Five queries in each
Run with the tester’s RFC 9535 core, jq 1.7.1 and the jmespath Python package 1.1.0:
one value JSONPath $.store.bicycle.color
jq .store.bicycle.color
JMESPath store.bicycle.color
every title JSONPath $.store.book[*].title
jq .store.book[].title
JMESPath store.book[*].title
a filter JSONPath $.store.book[[email protected] < 10].title
jq .store.book[] | select(.price < 10) | .title
JMESPath store.book[?price < `10`].title
the last one JSONPath $.store.book[-1].title
jq .store.book[-1].title
JMESPath store.book[-1].title
at any depth JSONPath $..price
jq [.. | objects | select(has("price")) | .price]
JMESPath (none)
$..price and the jq line both give 8.95, 12.99, 8.99, 22.99, 399. JMESPath has no recursive descent, so store..price is a parse error and each level has to be written out.
Where they differ
- What comes back. JSONPath selects nodes, each with a normalized path such as
$['store']['book'][2]['title']. jq yields a stream:"Sayings of the Century"and"Moby Dick"print as two separate values, and[ … ]around the filter collects them into an array. JMESPath returns one JSON value, here["Sayings of the Century", "Moby Dick"]. - Missing members.
$.store.book[0].isbnselects nothing. jq and JMESPath both returnnull, the same as for a member that holdsnull. - Comparing across types. JSONPath’s
@.price < "10"is false for every book. jq orders all values, numbers before strings, soselect(.price < "10")keeps all four. The JMESPath spec says<on anything but numbers yieldsnull, which drops the element; the Python package raises aTypeErrorinstead. - Literals. JMESPath writes JSON literals in backticks and raw strings in single quotes.
price < 10without backticks is a parse error in the Python package. - Reshaping. jq and JMESPath build new objects,
{title, price}and{title: title, price: price}. JSONPath only selects; it can’t rename, compute or construct.
Which one you’ll meet
- JSONPath has been an IETF standard since February 2024 (RFC 9535); libraries such as Jayway JsonPath for Java and jsonpath-plus for JavaScript are older and differ from it in places.
kubectl -o jsonpathtakes Kubernetes’ own template form, in braces:{.items[*].metadata.name}. - jq is a command-line program and a full language, with variables, functions and arithmetic.
gh --jqtakes its syntax. - JMESPath is what
aws --queryandaz --querytake, with a written specification at jmespath.org.