JSON Queries

Query and filter JSON data efficiently using JSONPath and JMESPath query languages.

What are JSON Queries?

JSON query languages allow you to extract specific data from complex JSON structures without writing custom parsing code. Think of them as SQL for JSON.

The two most popular query languages are:

  • JSONPath: XPath for JSON, simple and intuitive
  • JMESPath: More powerful, with filtering and transformations

JSONPath

JSONPath uses a dot-notation syntax similar to accessing object properties in JavaScript.

Sample Data

{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    }
}

Basic Syntax

Expression Description Result
$.store.book[0].title First book title "Sayings of the Century"
$.store.book[*].author All authors ["Nigel Rees", "J. R. R. Tolkien"]
$..price All prices [8.95, 22.99, 19.95]
$.store.book[?(@.price < 10)] Books under $10 [{first book object}]

JSONPath Operators

  • $ - Root element
  • @ - Current element
  • . or [] - Child operator
  • .. - Recursive descent
  • * - Wildcard (all elements)
  • [] - Array subscript
  • [start:end] - Array slice
  • ?() - Filter expression

JMESPath

JMESPath provides more advanced querying and transformation capabilities.

Basic Examples

Expression Description
store.book[0].title Simple property access
store.book[*].author Projection (all authors)
store.book[?price < `10`] Filtering
store.book[*].{title: title, price: price} Multi-select hash
max(store.book[*].price) Built-in function

Advanced Features

Filtering

// Books by specific author
store.book[?author == 'J. R. R. Tolkien']

// Books between $10 and $25
store.book[?price >= `10` && price <= `25`]

// Fiction category books
store.book[?category == 'fiction']

Projections

// Get all titles
store.book[*].title

// Get title and price for all books
store.book[*].{title: title, price: price}

Functions

// Maximum price
max(store.book[*].price)

// Minimum price
min(store.book[*].price)

// Number of books
length(store.book)

// Sort by price
sort_by(store.book, &price)

// Reverse array
reverse(store.book)

Using in Code

JSONPath in JavaScript

const jp = require('jsonpath');

const data = {
    store: {
        book: [
            { title: "Book 1", price: 10 },
            { title: "Book 2", price: 20 }
        ]
    }
};

// Query all titles
const titles = jp.query(data, '$.store.book[*].title');
console.log(titles); // ["Book 1", "Book 2"]

// Filter by price
const cheap = jp.query(data, '$.store.book[?(@.price < 15)]');
console.log(cheap); // [{ title: "Book 1", price: 10 }]

JMESPath in Python

import jmespath

data = {
    'store': {
        'book': [
            {'title': 'Book 1', 'price': 10},
            {'title': 'Book 2', 'price': 20}
        ]
    }
}

# Query all titles
titles = jmespath.search('store.book[*].title', data)
print(titles)  # ['Book 1', 'Book 2']

# Filter and transform
result = jmespath.search(
    'store.book[?price > `10`].{name: title, cost: price}',
    data
)
print(result)  # [{'name': 'Book 2', 'cost': 20}]

JSONPath vs JMESPath

Feature JSONPath JMESPath
Syntax XPath-like Custom, cleaner
Filtering Basic Advanced
Functions Limited Many built-in
Transformations No Yes
Learning Curve Easy Moderate
Performance Fast Very Fast

Use Cases

  • API Response Processing: Extract specific fields from complex responses
  • Configuration Management: Query configuration files
  • Data Transformation: Transform JSON before sending
  • Testing: Validate API responses in tests
  • Monitoring: Extract metrics from log data
  • CLI Tools: Query JSON from command line (jq)

Best Practices

  • Start with simple queries and build complexity gradually
  • Use JSONPath for simple extractions
  • Use JMESPath when you need transformations or complex filtering
  • Test queries with sample data first
  • Consider performance for large datasets
  • Document complex queries with comments
  • Use online testers for development and debugging