JQ
Apply JQ queries to transform JSON records using the full power of JQ syntax.
Overview
The JQ transform allows you to filter, reshape, and manipulate JSON data using JQ query syntax. It supports both direct output of query results and storing results under specified keys in the original record.
Queries are executed by gojq v0.12.19, a pure-Go jq
implementation, rather than by the jq binary. Its behavior differs from jq in a few documented
ways, so check the gojq documentation if a query behaves differently here than on your command
line.
Example
This example shows how to use the JQ transformation to filter and reshape JSON records using JQ query syntax.
Code
Given the input record:
Code
With key specified, the output record will be:
Code
Without key specified, the output will be just the query result:
Code
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | The JQ query to execute |
| key | string | No | Optional key to store the result under in the original record |
| prevent_data_dropping | boolean | No | Defaults to false. When true, the transform errors instead of dropping the record if the query produces no output. Has no effect when key is set |
More Examples
- Delete sensitive fields:
Code
- Compute new fields and store under a key:
Code
- Complex data reshaping:
Code
- Array aggregation with nested filtering:
Code
Output Behavior
-
Direct Output (no key specified):
- Query must return a JSON object or array
- Single results are returned directly
- Multiple results are wrapped in an array
- A query producing no output drops the record, which is how queries such as
select(...)filter data. Setprevent_data_droppingtotrueto error instead - Non-object/array results (strings, numbers, booleans) will cause an error
-
Key Storage (key specified):
- Query result is stored under the specified key
- Original record structure is preserved
- Supports all JSON value types (objects, arrays, strings, numbers, booleans, null)
- Nested key paths are supported (e.g., "metadata.calculated.total")
- Overwrites any existing value at the key path
- A record is never dropped: a query producing no output writes
nullat the key.prevent_data_droppingtherefore has no effect here
Error Handling
The transform will fail with an error in these cases:
- Missing or empty query
- Query fails to parse or compile
- Query execution error
- Direct output (no key) returns a non-object/array value
- Invalid JSON in input record
- Invalid JSON output from query
- Direct output (no key) produces no output while
prevent_data_droppingistrue
Preventing Silent Drops
A jq query that produces no output for a record drops that record. This is intentional when the query is filtering, but it is easy to do by accident: a typo in a field name, or a select condition that never matches, silently removes data with no error.
Set prevent_data_dropping to true when the query is only meant to reshape records, never to filter them:
Code
If a record reaches this transform and the query yields nothing, the pipeline node reports an error rather than dropping the record. Leave the field unset (or false) for queries that are meant to filter, such as select(.severity == "high").
Records that fail this check are retried, so a query that drops records consistently will keep the node in an erroring state until the query or the setting is corrected.
Common JQ Patterns
- Filter objects:
select(.field == "value") - Access nested fields:
.parent.child.field - Create objects:
{new_field: .old_field} - Array operations:
map,add,length - Delete fields:
del(.field_name) - String operations:
split,join,ascii_downcase - Mathematical operations:
add,multiply
One Record In, Many Records Out
Without key, every value the query emits becomes its own output record. A query of .items[]
against a record whose items array holds three elements produces three records, each
continuing through the pipeline independently:
Code
Code
produces three records:
Code
This is the idiomatic way to split a batched payload — a vendor API that returns many events wrapped in one envelope — into individual records.
With key set, the record count never changes: a single result is written to that key as-is, and
multiple results are written to it as an array.