json

FormatValidateConvert

In this section · 04 Search itFind

04 · Search it

Find and query JSON

Search a document for text, a pattern or a JSONPath query, then narrow the view to the matches or take them away as a document of their own.

Guide 4 of 9 in Editor

Searching is one of the jobs the editor is for, and every document you open there can be searched from one bar. It opens under a pane’s toolbar, it looks for text in the keys and values of the JSON rather than in its punctuation, and it can be switched to a pattern or to a structural query when a word is not precise enough. What it finds, it can also keep: narrow the Tree to the matching rows, or copy the matches into the other pane as a document you can save.

Each section below starts with an example you can repeat. Paste the input into the left pane of the editor, follow the steps with the controls named as the bar names them, and compare what you see with the result. The result shows the counter first, then each match as a JSON Pointer, which is the path from the top of the document written with slashes. Three subjects need more room than a card and have pages of their own: regular expressions, JSONPath, and a cheat sheet of every query the bar reads.

Under every example there is Try it in the editor. It opens the editor in this tab with that input already in the left pane and the search the steps begin with already in the Find bar, so the counter on screen is the counter printed below. The presses the steps name are still yours to make. If the editor already holds a document it asks before replacing it, and one press of Ctrl+Z (⌘Z on a Mac) puts your document back.

Find text in a document

Input

{ "name": "Ines", "city": "Lisbon", "note": "Ines moved to Porto" }

Do

  1. Press Find in the editor band, or ⌘F (Ctrl+F on Windows and Linux).
  2. Type ines into Find in this document…

Result

1/2
/name
/note

Try it in the editor →

Both the value Ines and the note that mentions her count, so the counter reads two matches with the first one current. The key name sits next to the first match but is not one, because the bar compares the word with each key and each value on its own. Case does not matter until you ask it to.

Enter moves to the next match and Shift+Enter to the one before, and the pane scrolls to keep the current match in view. The two arrow buttons, Previous match and Next match, do the same with a pointer. The small cross inside the field is Clear the query: it empties the box and keeps the bar open for a new search. The cross at the far right of the bar is Close find, which Esc also presses. With the caret inside the Code view, ⌘F opens the bar for that pane rather than the browser’s own search, which would see only the lines on screen.

Match case

Input

{ "status": "OK", "message": "ok, retrying" }

Do

  1. Press Find in the editor band, or ⌘F (Ctrl+F on Windows and Linux).
  2. Type ok.
  3. Press Match case (Aa).

Result

Match case off: 1/2
/status
/message

Match case on: 1/1
/message

Try it in the editor →

Without it, ok finds the status and the message alike, because the bar folds upper and lower case together. Press Match case, shown on the bar as Aa, and the capitals have to agree: the status holds OK, so only the message is left.

Folding is the right default for prose, where a name at the start of a sentence gains a capital. JSON is full of values where case carries meaning, such as enum strings, currency codes, HTTP methods and identifiers that differ by one letter. Turn it on when those are what you are after. The button stays pressed until you press it again, and it applies to regular expressions too, where it decides whether the pattern is compiled with the i flag.

Keys, values or both

Input

{ "id": 7, "user_id": 42, "note": "see id 7" }

Do

  1. Press Find in the editor band, or ⌘F (Ctrl+F on Windows and Linux).
  2. Type id.
  3. Open Search scope (K·V) and pick Keys only, then open it again and pick Values only.

Result

Keys and values: 1/3
/id
/user_id
/note

Keys only: 1/2
/id
/user_id

Values only: 1/1
/note

Try it in the editor →

A short word like id turns up everywhere: in the key id, inside the key user_id, and in the note that happens to mention one. The number 7 is not a match, because the bar reads a number as the digits it was written with, and those hold no letters.

Search scope is the button beside the query toggles. It opens a small menu of three choices: Keys and values, the default, then Keys only and Values only. The button itself shows the choice in short, as K·V, K or V, and its tooltip spells it out. Keys only is how you find every field with a name like this; values only is how you find the data without the schema getting in the way. Scope is for text searches. In Query mode the button is greyed out, because a path already says which part of the document to look at.

Find with regular expressions

Press Regular expression, shown as .*, and the query becomes a pattern. That is how you find every address at one domain, every date written as year, month and day, every key that ends in _id, or every empty string. The pattern is tested against each key and each value separately, so the anchors ^ and $ mean the start and the end of one value. A pattern that cannot be compiled is not ignored: the counter shows the browser’s reason instead of a count. Read the regular expressions guide for five worked patterns and the rules behind them.

Query JSON with JSONPath

Text finds words; a query finds places in the structure. Press Query mode, shown as { }, and the bar reads JSONPath, the standard way to write a route through a JSON document. $.orders[[email protected] > 100].id asks for the identifier of every order over one hundred, and it keeps working however many orders the file holds. The JSONPath guide works that example through, from the query to the extracted result.

JSONPath cheat sheet

Once the idea is clear, the details are what you look up: how a slice counts, which comparison operators exist, and what this editor adds to the standard. The cheat sheet lists every construct Query mode reads, one row each, all of them run on the same small bookshop document so you can see exactly which paths each one selects. It ends with the parts of the standard the bar does not read.

Show only the matches

Input

{
  "users": [
    { "name": "Ines", "email": "[email protected]", "role": "admin" },
    { "name": "Marco", "email": "[email protected]", "role": "editor" }
  ]
}

Do

  1. Press Find in the editor band, or ⌘F (Ctrl+F on Windows and Linux).
  2. Type admin.
  3. Press Filter to matches.

Result

root {…}
  users: […]
    0: {…}
      role: "admin"

Try it in the editor →

Filter to matches is the funnel button. It hides every row that is not a match or on the path down to one, so what is left is the answer and the route to it. Here the only match is Ines’s role, so the Tree keeps her entry and the array above it, and drops her name, her email and all of Marco. A match that is a whole object keeps everything inside it: in Query mode, role == 'admin' matches Ines’s entry itself, and the filter keeps her name and email too.

Filtering works on rows, so it needs a Tree, Table or Graph view. In Code the button refuses and says why: Filter needs Tree, Table or Graph — Code shows the whole document. The filter lasts as long as the bar is open. Closing the bar always brings every row back, so a document can never sit half hidden with nothing on screen to explain it.

Extract the matches as a new document

Input

{
  "users": [
    { "name": "Ines", "email": "[email protected]", "role": "admin" },
    { "name": "Marco", "email": "[email protected]", "role": "editor" }
  ]
}

Do

  1. Press Find in the editor band, or ⌘F (Ctrl+F on Windows and Linux).
  2. Press Query mode ({ }) on the bar.
  3. Type $..email.
  4. Press Extract matches into the other pane.

Result

{
  "users": [
    {
      "email": "[email protected]"
    },
    {
      "email": "[email protected]"
    }
  ]
}

Try it in the editor →

Extract matches into the other pane turns the answer into data. It writes a new document into the other pane, named after the source with .matches.json on the end, and it keeps the shape around each match: the emails are still inside users, while every name and role is gone and the array closes up.

From Mirror, where both panes show one document, the editor switches to Compare first, since the other pane needs a document of its own. The status bar then says Extracted 2 matches into the right pane. Switched to Compare; differences are not highlighted. The differences are left unmarked because an extract differs from its source almost everywhere. If the other pane holds work of yours, the editor asks before replacing it, and when nothing matched the button refuses rather than writing an empty document.

Find in Mirror and in Compare

Input

Any document, in Mirror and then in Compare.

Do

  1. In Mirror, press Find and type a word the document holds.
  2. With the bar still open, switch the band to Compare.

Result

Mirror: one bar, its matches marked in Code on the left and in the Tree on the right. Compare: a second bar opens, and each pane has its own query and counter.

In Mirror the two panes are two views of one document, so there is one search. The bar opens on the left whichever toolbar you press Find in, and its matches are marked in both views at once: highlighted in the Code on the left, and as rows in the Tree on the right. Stepping with Enter moves both.

In Compare each pane holds its own document, so each gets its own bar, its own query and its own counter, and switching into Compare with the bar open opens the second one for you. That is useful when the two files share a shape. Search for the same key in both to line up the values you want to compare, or run a query on one side only. Switching back to Mirror keeps the left pane’s search and closes the right one.

What a search will not do

The bar counts up to ten thousand matches and then stops, and the counter says so by putting a plus after the total, as 1/10,000+. Every match it did collect still works: stepping, filtering and extracting all behave normally, and a narrower query brings the figure back under the ceiling. The same ceiling is why a query over a very large file stays quick.

A search reads the document as it has been parsed, so while the JSON is broken the bar searches the part that parsed and ignores the rest. Repair it, or fix the marked error, and the missing matches appear. Find never changes anything either: it reads the document, marks it, and only Extract writes, and then only into the other pane.

Open the editor to search your own data, or read the next guide, Find with regular expressions.