Query JSON using JSONata

Updated: May 4, 2026

This example shows how to read a JSON document (or any other supported format) and query or transform it using JSONata expressions with DataPipeline.

 

Input JSON File

[
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batters":
    {
      "batter":
      [
        { "id": "1001", "type": "Regular" },
        { "id": "1002", "type": "Chocolate" },
        { "id": "1003", "type": "Blueberry" },
        { "id": "1004", "type": "Devil's Food" }
      ]
    },
    "topping":
    [
      { "id": "5001", "type": "None" },
      { "id": "5002", "type": "Glazed" },
      { "id": "5005", "type": "Sugar" },
      { "id": "5007", "type": "Powdered Sugar" },
      { "id": "5006", "type": "Chocolate with Sprinkles" },
      { "id": "5003", "type": "Chocolate" },
      { "id": "5004", "type": "Maple" }
    ]
  },
  {
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batters":
    {
      "batter":
      [
        { "id": "1001", "type": "Regular" }
      ]
    },
    "topping":
    [
      { "id": "5001", "type": "None" },
      { "id": "5002", "type": "Glazed" },
      { "id": "5005", "type": "Sugar" },
      { "id": "5003", "type": "Chocolate" },
      { "id": "5004", "type": "Maple" }
    ]
  }
]

 

Java code listing

package com.northconcepts.datapipeline.examples.jsonata;

import com.northconcepts.datapipeline.core.Record;
import com.northconcepts.datapipeline.core.ValueNode;

import java.io.FileReader;

import static com.northconcepts.datapipeline.jsonata.Jsonata.jsonata;


public class QueryJsonUsingJSONata {

    public static void main(String[] args) throws Throwable {
        try (FileReader fileReader = new FileReader("data/input/nested-data.json")) {
            ValueNode data = Record.fromJson(fileReader);

            printSection("Basic Selection");
            runQuery("Query 1 - Donut Names", "name", data);
            runQuery("Query 2 - Batter Types", "batters.batter.type", data);

            printSection("Filtering");
            runQuery("Query 3 - Donut Named Raised", "$[name='Raised']", data);
            runQuery("Query 4 - Donut with Chocolate with Sprinkles Topping", "$[topping[type='Chocolate with Sprinkles']].name", data);

            printSection("Reshaping");
            runQuery("Query 5 - Name With Batter And Topping Counts",
                    "{'name': name, 'batterCount': $count(batters.batter), 'toppingCount': $count(topping)}",
                    data);
            runQuery("Query 6 - Donut Summary",
                    "{'id': id, 'name': name, 'pricePerUnit': ppu}",
                    data);

            printSection("Metrics");
            runQuery("Query 7 - Total Donuts", "$count($)", data);
            runQuery("Query 8 - Average Price Per Unit", "$average(ppu)", data);
        }
    }

    private static void runQuery(String title, String expression, ValueNode data) {
        System.out.println(title);
        System.out.println("Expression: " + expression);
        System.out.println("Result: ");
        System.out.println(jsonata(expression).evaluate(data));
    }

    private static void printSection(String title) {
        System.out.println("==============================================================");
        System.out.println(title);
    }
}

 

Code walkthrough

  1. Read JSON into memory
    • Record.fromJson(fileReader) parses the file and returns a ValueNode tree. All queries run against that tree.
  2. Execute JSONata expressions
    • runQuery prints the query name, the expression, and the evaluated result from jsonata(expression).evaluate(data)
  3. Query patterns used
    • Basic Selection: These expressions navigate fields and nested arrays.
      • name
      • batters.batter.type
    • Filtering: These expressions keep only records that match conditions.
      • $[name='Raised']
      • $[topping[type='Chocolate with Sprinkles']].name
    • Reshaping: These expressions build new objects with only the fields you want.
      • {'name': name, 'batterCount': $count(batters.batter), 'toppingCount': $count(topping)}
      • {'id': id, 'name': name, 'pricePerUnit': ppu}
    • Metrics: These expressions compute aggregate values.
      • $count($)
      • $average(ppu)

 

Console Output

==============================================================
Basic Selection
Query 1 - Donut Names
Expression: name
Result:
[
  "Cake",
  "Raised"
]
Query 2 - Batter Types
Expression: batters.batter.type
Result:
[
  "Regular",
  "Chocolate",
  "Blueberry",
  "Devil's Food",
  "Regular"
]
==============================================================
Filtering
Query 3 - Donut Named Raised
Expression: $[name='Raised']
Result:
[
  {
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batters": {
      "batter": [
        {
          "id": "1001",
          "type": "Regular"
        }
      ]
    },
    "topping": [
      {
        "id": "5001",
        "type": "None"
      },
      {
        "id": "5002",
        "type": "Glazed"
      },
      {
        "id": "5005",
        "type": "Sugar"
      },
      {
        "id": "5003",
        "type": "Chocolate"
      },
      {
        "id": "5004",
        "type": "Maple"
      }
    ]
  }
]
Query 4 - Donut with Chocolate with Sprinkles Topping
Expression: $[topping[type='Chocolate with Sprinkles']].name
Result:
"Cake"
==============================================================
Reshaping
Query 5 - Name With Batter And Topping Counts
Expression: {'name': name, 'batterCount': $count(batters.batter), 'toppingCount': $count(topping)}
Result:
[
  {
    "name": "Cake",
    "batterCount": 4,
    "toppingCount": 7
  },
  {
    "name": "Raised",
    "batterCount": 1,
    "toppingCount": 5
  }
]
Query 6 - Donut Summary
Expression: {'id': id, 'name': name, 'pricePerUnit': ppu}
Result:
[
  {
    "id": "0001",
    "name": "Cake",
    "pricePerUnit": 0.55
  },
  {
    "id": "0002",
    "name": "Raised",
    "pricePerUnit": 0.55
  }
]
==============================================================
Metrics
Query 7 - Total Donuts
Expression: $count($)
Result:
2
Query 8 - Average Price Per Unit
Expression: $average(ppu)
Result:
0.55
Mobile Analytics