Skip to content

JSON query: run JSONPath on any JSON

Type a JSONPath query, see every match with its path, and turn the result into a new document or a file.

Queries run on this device, in a background worker. Your JSON is never uploaded. How your data stays local.

Local
source
result
Loading the workspace...

JSON Mill's JSON query tool runs JSONPath, the query language standardized as RFC 9535, against the document in the workspace. Type a query such as $.orders[*].customer.email and the Query view lists every match with its path and a preview of its value, updating as you type.

Click a match to jump to it in the tree. When the result is what you need, Use result as document replaces the source with the matched values as one JSON array, and Export result downloads them as JSON, CSV, Excel or JSON Lines. Numbers keep their exact text throughout, so long IDs and prices are never rounded.

How to run a JSONPath query

  1. Paste or open your JSON. Paste it, drop a file on the workspace or press Open file. This page opens in the Query view; JSON Lines files work too, with each line as one item of an array.
  2. Type a query. Start with $, the root of the document. Press one of the example buttons under the box to start from a common pattern. The match count updates as you type, and a mistake shows a one-line message with the character where the query went wrong.
  3. Check the matches. Each match shows its path, such as $.orders[3].customer.email, and its value. Click a match to open the Tree view at that value and see what surrounds it.
  4. Use or export the result. Press Use result as document to make the matches your new document (undo puts the original back), or Export result to download them as JSON, CSV, Excel or JSON Lines.

Example: emails of paid orders over 100

An order export with mixed statuses and totals, queried for the email of every paid order of 100 or more.

orders.json
{
  "store": "Fernway Outfitters",
  "orders": [
    {
      "id": 5012000000000000001,
      "status": "paid",
      "total": 162.50,
      "customer": { "name": "Ada Byrne", "email": "ada@example.com" }
    },
    {
      "id": 5012000000000000002,
      "status": "refunded",
      "total": 240.00,
      "customer": { "name": "Tomas Lind", "email": "tomas@example.com" }
    },
    {
      "id": 5012000000000000003,
      "status": "paid",
      "total": 48.90,
      "customer": { "name": "Mei Tan", "email": "mei@example.com" }
    },
    {
      "id": 5012000000000000004,
      "status": "paid",
      "total": 100,
      "customer": { "name": "Ravi Shah", "email": "ravi@example.com" }
    }
  ]
}
Matches for $.orders[?@.status == 'paid' && @.total >= 100].customer.email
2 matches
$.orders[0].customer.email = "ada@example.com"
$.orders[3].customer.email = "ravi@example.com"

The filter [?...] keeps the orders where both tests hold, and .customer.email then picks one value from each. The order with a total of exactly 100 matches because the test is >=; the refunded order is left out even though its total is higher.

Options

Settings in the workspace that matter for this job
Option What it does
Example queries One click fills in a common pattern: every name in an array, every price anywhere in the document, or every item that has an active field.
Recent queries Queries you run with Enter, an example, or an action are kept as buttons under the box for this session.
Use result as document Replaces the source with every matched value, as one formatted JSON array, in a single undoable step.
Export result Opens the Export menu set to the matches instead of the whole document, with every format and cleaning option the menu offers.

Limits

  • The query language is JSONPath as defined in RFC 9535. jq, JMESPath and JSONata syntax are not supported.
  • The list shows the first 5,000 matches. The count, Use result as document and Export result always include every match.
  • When an object repeats a key, queries see only the last value for that key, the same as JSON.parse and the table view.
  • Use result as document writes strings with standard JSON escaping, so an escape such as \u00e9 in the source becomes the character it stands for. Numbers keep their exact text.
  • Query history lasts until you reload the page. Nothing about your queries is stored or sent anywhere.

Questions

What is JSONPath?
JSONPath is a query language for JSON, standardized in 2024 as RFC 9535. A query starts at $, the root, and steps into the document: .name or ['name'] for a key, [0] for an array item, [*] for every child, .. for any depth, [1:3] for a slice and [?...] for a filter.
How do I filter an array by a value?
Use a filter selector, where @ is the item being tested. $.orders[?@.status == 'paid'] keeps paid orders, $.orders[?@.total > 100] compares numbers, and &&, || and ! combine tests. $[?@.active] keeps the items that have an active field at all.
Which JSONPath functions are supported?
All five from RFC 9535: length() for the length of a string, array or object, count() for the number of nodes a query selects, match() and search() for regular expressions, and value() to compare the single value a query selects.
Why does my query show an error?
The message names the character where the query stopped making sense, counting from 1. Common causes are a missing $ at the start, a missing ], double quotes inside a filter that is already in double quotes, or comparing a query that can select many values, such as one with * or ...
Are large numbers compared exactly?
Yes. Numbers are compared by their exact decimal value, so $[?@.id == 9007199254740993] finds that ID and not its rounded neighbor, and 1.0 == 1 is true. The matches keep the number text exactly as it is in your file.

Last updated