JSON Query

JSON Query allows you to query and extract data from JSON documents using JavaScript-like syntax. The query language provides a powerful way to navigate, filter, and transform JSON data.

Basic Concept

In JSON Query, root represents the root of the JSON document. All queries start from this root reference and navigate through the JSON structure using JavaScript object notation.

Syntax Overview

Basic Access

// Access root object
root

// Access property
root.propertyName

// Access array element
root.arrayName[0]

// Access nested property
root.user.profile.name

Array Operations

// Get array length
root.users.length

// Access first element
root.users[0]

// Access last element
root.users[root.users.length - 1]

// Get all elements (returns the array)
root.users

Query Examples

Sample JSON Data

{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville", 
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  },
  "users": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]",
      "age": 30,
      "active": true,
      "address": {
        "street": "123 Main St",
        "city": "New York",
        "zipcode": "10001"
      }
    },
    {
      "id": 2,
      "name": "Jane Smith", 
      "email": "[email protected]",
      "age": 25,
      "active": false,
      "address": {
        "street": "456 Oak Ave",
        "city": "Los Angeles", 
        "zipcode": "90210"
      }
    }
  ]
}

Basic Queries

// Get all books
root.store.book

// Get first book
root.store.book[0]

// Get book title
root.store.book[0].title

// Get bicycle color
root.store.bicycle.color

// Get all users
root.users

// Get user address
root.users[0].address.city

Advanced Queries

// Get book by condition (using find-like logic)
root.store.book.find(book => book.category === "fiction")

// Get all book titles
root.store.book.map(book => book.title)

// Filter books by price
root.store.book.filter(book => book.price < 10)

// Check if any book has ISBN
root.store.book.some(book => book.isbn)

// Get all authors
root.store.book.map(book => book.author)

// Count fiction books
root.store.book.filter(book => book.category === "fiction").length

// Get user by condition
root.users.find(user => user.active === true)

// Get all user cities
root.users.map(user => user.address.city)

Array Methods

Filtering

// Filter books by price
root.store.book.filter(book => book.price > 10)

// Filter books by property existence
root.store.book.filter(book => book.isbn)

// Filter books by category
root.store.book.filter(book => book.category === "fiction")

// Filter users by age
root.users.filter(user => user.age > 25)

// Filter users by city
root.users.filter(user => user.address.city === "New York")

Mapping

// Extract book titles
root.store.book.map(book => book.title)

// Create new book objects
root.store.book.map(book => ({
  title: book.title,
  author: book.author,
  category: book.category
}))

// Transform book data
root.store.book.map(book => `${book.title} by ${book.author}`)

// Extract user names
root.users.map(user => user.name)

// Transform user addresses
root.users.map(user => `${user.name} lives in ${user.address.city}`)

Finding

// Find book by category
root.store.book.find(book => book.category === "fiction")

// Find book by author
root.store.book.find(book => book.author === "Herman Melville")

// Find book index by title
root.store.book.findIndex(book => book.title === "Moby Dick")

// Find user by id
root.users.find(user => user.id === 1)

// Find user by city
root.users.find(user => user.address.city === "Los Angeles")

Aggregation

// Count books
root.store.book.length

// Sum book prices
root.store.book.reduce((sum, book) => sum + book.price, 0)

// Get average book price
root.store.book.reduce((sum, book) => sum + book.price, 0) / root.store.book.length

// Check if all books have authors
root.store.book.every(book => book.author)

// Check if any book has ISBN
root.store.book.some(book => book.isbn)

// Count users
root.users.length

// Sum user ages
root.users.reduce((sum, user) => sum + user.age, 0)

// Check if any user is active
root.users.some(user => user.active)

Object Operations

Property Access

// Direct property access
root.store.bicycle.color

// Bracket notation (useful for dynamic properties)
root.store["bicycle"]["color"]

// Nested access
root.users[0].address.street

// Book property access
root.store.book[0].author

Property Checking

// Check if property exists
"bicycle" in root.store

// Check property value
root.store.bicycle.color === "red"

// Check nested property
root.users[0] && root.users[0].address

// Check book property
root.store.book[0] && root.store.book[0].isbn

Conditional Logic

// Ternary operator
root.store.bicycle.color === "red" ? "Red Bicycle" : "Other Color"

// Logical operators for books
root.store.book.filter(book => book.category === "fiction" && book.price < 10)

// Logical operators for users
root.users.filter(user => user.active && user.age > 25)

// Nullish coalescing
root.store.book[0].isbn ?? "No ISBN"

// Optional chaining
root.users[0]?.address?.zipcode

Common Patterns

Data Extraction

// Extract book summary
root.store.book.map(book => ({
  title: book.title,
  author: book.author,
  category: book.category,
  price: book.price
}))

// Extract user summary
root.users.map(user => ({
  name: user.name,
  email: user.email,
  status: user.active ? "Active" : "Inactive",
  city: user.address.city
}))

// Get store summary
{
  totalBooks: root.store.book.length,
  bicycleColor: root.store.bicycle.color,
  userCount: root.users.length,
  averageBookPrice: root.store.book.reduce((sum, book) => sum + book.price, 0) / root.store.book.length
}

Data Validation

// Check book data integrity
root.store.book.every(book => book.title && book.author && book.price)

// Check user data integrity
root.users.every(user => user.id && user.name && user.email && user.address)

// Validate structure
root.store.book && Array.isArray(root.store.book)
root.users && Array.isArray(root.users)

// Check required fields
root.store.book.filter(book => !book.title).length === 0
root.users.filter(user => !user.address.city).length === 0

Data Transformation

// Group books by category
root.store.book.reduce((groups, book) => {
  const category = book.category;
  groups[category] = groups[category] || [];
  groups[category].push(book);
  return groups;
}, {})

// Group users by city
root.users.reduce((groups, user) => {
  const city = user.address.city;
  groups[city] = groups[city] || [];
  groups[city].push(user);
  return groups;
}, {})

// Create book lookup by title
root.store.book.reduce((lookup, book) => {
  lookup[book.title] = book;
  return lookup;
}, {})

// Create user lookup by id
root.users.reduce((lookup, user) => {
  lookup[user.id] = user;
  return lookup;
}, {})

Best Practices

  1. Start with root: Always begin queries with root to reference the document root
  2. Handle undefined values: Use optional chaining (?.) for safe property access
  3. Use meaningful variable names: In array methods, use descriptive parameter names
  4. Chain operations: Combine filter, map, and other methods for complex queries
  5. Check data types: Verify array and object types before applying methods
  6. Use bracket notation: For dynamic property names or properties with special characters

Error Handling

// Safe property access
root.users?.[0]?.address?.city
root.store.book?.[0]?.isbn

// Default values
root.store.bicycle?.color || "unknown"
root.store.book?.[0]?.isbn || "No ISBN"

// Type checking
Array.isArray(root.store.book) ? root.store.book.length : 0
Array.isArray(root.users) ? root.users.length : 0

// Existence checking
root.store.book && root.store.book.length > 0 ? root.store.book[0] : null
root.users && root.users.length > 0 ? root.users[0] : null

This query language provides a flexible and powerful way to extract, filter, and transform data from JSON documents using familiar JavaScript syntax.