Records (objects) contain key-value pairs. This guide shows you how to work with records — accessing fields, extracting keys, combining fragments, and transforming values.
Access record fields
Section titled “Access record fields”Get values using dot notation or brackets:
from { user: { name: "Alice", age: 30, address: { city: "NYC", zip: "10001" } }}name = user.namecity = user.address.cityzip = user["address"]["zip"]has_email = user.has("email"){ user: { name: "Alice", age: 30, address: {city: "NYC", zip: "10001"} }, name: "Alice", city: "NYC", zip: "10001", has_email: false}Get keys and values
Section titled “Get keys and values”Extract field names and values:
from { config: { host: "localhost", port: 8080, ssl: true }}field_names = config.keys()// Note: values() function is not availablenum_fields = config.keys().length(){ config: {host: "localhost", port: 8080, ssl: true}, field_names: ["host", "port", "ssl"], num_fields: 3}Combine records with spread
Section titled “Combine records with spread”Use the spread operator ... to combine records. Spread keeps the resulting
record visible where you construct it, and lets you mix existing fragments with
literals or computed fields. Later fields overwrite earlier fields, so put
defaults first and overrides last:
from { defaults: {host: "localhost", port: 80, ssl: false}, custom: {port: 8080, ssl: true}}service = { ...defaults, ...custom, debug: true,}{ defaults: {host: "localhost", port: 80, ssl: false}, custom: {port: 8080, ssl: true}, service: { host: "localhost", port: 8080, ssl: true, debug: true }}Use optional access when a record fragment may be missing. If the spread
expression evaluates to null, it contributes no fields, so an explicit
else {} fallback is not necessary:
from {account: {id: 1, name: "Alice"}}user = { ...account, ...account.profile?, active: true,}{ account: { id: 1, name: "Alice", }, user: { id: 1, name: "Alice", active: true, },}The merge function returns the same result for two records, including
null fragments, but prefer spread in transformation code when you construct the
resulting record.
Transform record values
Section titled “Transform record values”Note: The map_values function is not available in TQL. To transform record values, you would need to reconstruct the record with transformed values manually:
from { prices: { apple: 1.50, banana: 0.75, orange: 2.00 }}// Manual transformation example:with_tax = { apple: prices.apple * 1.1, banana: prices.banana * 1.1, orange: prices.orange * 1.1}Filter record fields
Section titled “Filter record fields”Keep explicit fields by constructing a new record. Use select_matching
and drop_matching when field names follow a pattern:
from { user: { id: 123, name: "Alice", email: "alice@example.com", password: "secret", api_key: "xyz123" }}public_info = { id: user.id, name: user.name, email: user.email}contact = { name: user.name, email: user.email}credentials = user.select_matching("(password|api_key)$")safe_user = user.drop_matching("(password|api_key)$"){ user: { id: 123, name: "Alice", email: "alice@example.com", password: "secret", api_key: "xyz123" }, public_info: { id: 123, name: "Alice", email: "alice@example.com" }, contact: { name: "Alice", email: "alice@example.com" }, credentials: { password: "secret", api_key: "xyz123" }, safe_user: { id: 123, name: "Alice", email: "alice@example.com" }}The matching functions inspect only top-level field names on the record you call them on. They don’t recurse into nested records.