$.store.book[0:2] selects the first two books, at indexes 0 and 1. A slice is [start:end:step] (RFC 9535 section 2.3.4): start is included, end is not, step defaults to 1, and any of the three can be left out. A negative bound counts from the end of the array, as in Python.
Slices on the bookstore
The RFC’s bookstore, in the tester below, has four books. With .title added to each query:
[0:2] Sayings of the Century, Sword of Honour
[:2] Sayings of the Century, Sword of Honour
[1:] Sword of Honour, Moby Dick, The Lord of the Rings
[-2:] Moby Dick, The Lord of the Rings
[::2] Sayings of the Century, Moby Dick
[1::2] Sword of Honour, The Lord of the Rings
[::-1] The Lord of the Rings, Moby Dick, Sword of Honour, Sayings of the Century
[3:1:-1] The Lord of the Rings, Moby Dick
Bounds past either end are clamped, so [0:100] selects all four books and never fails. [2:1] selects nothing, and so does a step of 0: RFC 9535 makes [::0] empty where Python raises an error. A slice of an object or a string selects nothing too.
The last element
$.store.book[-1].title is the last book’s title, "The Lord of the Rings", at the normalized path $['store']['book'][3]['title']. [-1:] selects the same node, as a slice.
[(@.length-1)] is how Goessner’s 2007 article wrote it: a script expression, handed to JavaScript to evaluate. RFC 9535 dropped script expressions, and the tester refuses this one and suggests [-1]. Libraries still differ here, in runs of each:
[-1] [-1:] [(@.length-1)] [::-1] [::2]
jsonpath-plus 11.1 nothing last last nothing works
Jayway 3.0.0 last last parse error parse error parse error
kubectl 1.32 last last parse error step error works
Jayway ignores steps: [0:4:2] returns all four books, [3:0:-1] none, and [::2] doesn’t parse. kubectl says step must be > 0, and jsonpath-plus returns every book for [::0]. [-1:] is the one spelling of “last” all of them accept.
Unions
A bracket can hold several selectors: $.store.book[0,1] is the first two books, and $.store.book[0:2,-1].title adds the last, three titles in all. Jayway refuses the second form, and jsonpath-plus drops the -1.
Elsewhere
jq .store.book[0:2] .store.book[-1] (no step)
JMESPath store.book[0:2] store.book[-1] store.book[::-1]
Python books[0:2] books[-1] books[::-1]
JavaScript books.slice(0, 2) books.at(-1) books.toReversed()