In this section · 04 Search itJSONPath cheat sheet
04 · Search it · Find and query JSON
JSONPath cheat sheet
Every construct Query mode reads, each run on one small document with the paths it selects.
Input
{
"owner": { "full name": "Ada Lovelace", "city": "London" },
"books": [
{ "title": "Dune", "price": 9.99, "tags": ["sf", "classic"], "inStock": true },
{ "title": "Emma", "price": 4.5, "tags": ["classic"], "inStock": false },
{ "title": "Neuromancer", "price": 12, "tags": ["sf"], "inStock": true }
]
}Do
- Press Find in the editor band, or
⌘F(Ctrl+Fon Windows and Linux). - Press Query mode (
{ }) on the bar. - Type
$.books[?@.price > 5].title.
Result
1/2
/books/0/title
/books/2/titleThis page is for looking things up. Every expression the Find bar reads in Query mode is here, one row each, and every row runs on the small bookshop document above: an owner and three books, each with a title, a price, a list of tags and a flag for whether it is in stock. For a slower walk through a single query, start with Query JSON with JSONPath. The rest of the bar is covered in the Find and query JSON guide.
How to read the table
The first column is what you type, with Query mode on. The second says in a few words what that form selects. The third lists the matches the bar reports for it on the bookshop document, in the order it steps through them, each written as a JSON Pointer. Paste the document into the editor, type any row, and the counter and the marked rows should agree with the table exactly. The one exception in form is the first row, whose match is the document itself.
The quickest way to that is Try it in the editor on the block above: it opens the editor on this same bookshop document with Query mode already on, and from there any expression in the table can be pasted straight into the bar, one after another, without loading the document again.
| Expression | Selects | Matches |
|---|---|---|
| Paths | ||
$ | the whole document | (the whole document) |
$.owner.city | a member, by name | /owner/city |
$.owner['full name'] | a member whose name has a space | /owner/full name |
$.books[0].title | an array item, counting from 0 | /books/0/title |
$.books[-1].title | counting from the end | /books/2/title |
$.books[0:2].title | a slice: from 0, stopping before 2 | /books/0/title/books/1/title |
$.books[::2].title | every second item | /books/0/title/books/2/title |
$.books[*].price | every item of an array | /books/0/price/books/1/price/books/2/price |
$.owner.* | every member of an object | /owner/full name/owner/city |
$..title | a name at any depth | /books/0/title/books/1/title/books/2/title |
$.books[1]..* | a node and everything below it | /books/1/books/1/title/books/1/price/books/1/tags/books/1/tags/0/books/1/inStock |
| Filters | ||
$.books[?@.price > 5].title | greater than | /books/0/title/books/2/title |
$.books[?@.price >= 12].title | greater than or equal | /books/2/title |
$.books[?@.price < 5].title | less than | /books/1/title |
$.books[?@.price <= 9.99].title | less than or equal | /books/0/title/books/1/title |
$.books[?@.title == 'Emma'].price | equal | /books/1/price |
$.books[?@.title != 'Dune'].title | not equal | /books/1/title/books/2/title |
| This editor’s operators | ||
$.books[?@.title ^= 'Neu'].title | starts with | /books/2/title |
$.books[?@.title $= 'ma'].title | ends with | /books/1/title |
$.books[?@.tags contains 'sf'].title | an array holding an item | /books/0/title/books/2/title |
$.books[?@.title contains 'man'].title | a string holding a substring | /books/2/title |
$.books[?@.title =~ /^[DE]/].title | a regular expression | /books/0/title/books/1/title |
| Combining tests | ||
$.books[?@.inStock].title | a bare field: present and truthy | /books/0/title/books/2/title |
$.books[?!@.inStock].title | not | /books/1/title |
$.books[?@.inStock && @.price < 10].title | and | /books/0/title |
$.books[?@.price < 5 || @.price > 10].title | or | /books/1/title/books/2/title |
$.books[?!(@.inStock && @.price > 5)].title | grouping with ( ) | /books/1/title |
price > 5 | a test on its own: every node that passes | /books/0/books/2 |
Paths
Every path starts at $, the document. A dot and a name step into a member, and square brackets with a quoted name do the same for a name a dot cannot carry, such as one with a space in it. A number in brackets picks an array item, counting from zero, and a negative number counts back from the end. A slice gives a start, an end that is left out, and a step, and any of the three can be skipped. A star stands for every member or every item, and two dots search downwards through all levels, which is how you find a name without knowing how deep it sits.
Filters
A filter keeps the items for which a test holds. It is written in square brackets that open with a question mark, and inside it @ is the item being tested. The six comparisons are the familiar ones. Numbers compare as numbers and strings as strings, and a string can be written in single or double quotes. A filter can be followed by more path, as most rows here are, to select a part of each item that passed rather than the whole item. The older style with the test in round brackets still works.
This editor’s operators
Four operators are not part of the JSONPath standard. They exist because a one-line search box is a poor place to type a function call, and they cover what the standard’s text functions are mostly used for. ^= tests how a string starts and $= how it ends. contains has two readings, both shown: a string that holds a piece of text, and an array that holds an item. =~ tests a regular expression written between slashes, which is case-sensitive unless you add the i flag after it. The Find with regular expressions guide has more on patterns.
Combining tests
Tests join with && for and, || for or, and ! for not, and round brackets group them the way they would in code. A field on its own, with no comparison, is a test too: it passes when the field exists and is not false, null or an empty string. Zero passes, and so does any object or array, even an empty one. The last row has no path at all. In Query mode a bare test is a whole query, and it matches every object in the document that passes, at any depth, which saves writing the path when only the condition matters.
What Query mode does not read
The standard defines five functions for use inside a filter: length(), count(), match(), search() and value(). None of them is read here, and typing one puts the reason where the counter was. The operators above stand in for the two text functions. A filter also cannot refer back to the document with $, so comparing a price with a budget stored elsewhere in the same file is not something one query can do. Both limits keep the language small enough to type in one line and to check as you type.
Open the editor or the JSONPath Tester to run these on your own data, or go back to all guides.