Skip to content

data.map

data.map transforms fields on every row. Each entry in fields defines an output column name and a template expression that computes its value. Expressions reference input columns, apply arithmetic, call string functions, or use conditionals.

Input: Table Output: Table

nodes:
compute-total:
type: data.map
config:
include_original: true
fields:
total: "{{ price * quantity }}"
label: "{{ category | upper }}"
FieldTypeRequiredDescription
fieldsmapyesOutput column name to template expression
include_originalbooleannoKeep all input columns alongside mapped fields. Default: false

When include_original is true, the output contains every input column plus the mapped fields. If a mapped field name matches an existing column, the mapped value replaces it in place. When false, the output contains only the mapped fields.

Expressions use {{ ... }} delimiters. Inside them, you reference columns by name and apply operations.

fields:
email_copy: "{{ email }}"
fields:
total: "{{ price * quantity }}"
margin: "{{ revenue - cost }}"
tax: "{{ subtotal * 0.19 }}"

Multiple {{ }} blocks in one expression produce string concatenation:

fields:
full_name: "{{ first_name }} {{ last_name }}"
greeting: "Hello {{ first_name }}!"

Filters transform values. Syntax: {{ field | filter }}.

FilterResult typeDescription
lowerstringLowercase
upperstringUppercase
trimstringStrip whitespace
lengthnumberString length
roundnumberRound to nearest integer
ceilnumberRound up
floornumberRound down
absnumberAbsolute value
to_stringstringCast to string
to_numbernumberCast to number (null on failure)
strip_currencynumberRemove currency symbols, parse as number
extract_numbernumberPull first numeric value from string
parse_date_dmydateParse dd/mm/yyyy
parse_date_mdydateParse mm/dd/yyyy
parse_date_ymddateParse yyyy-mm-dd
fields:
email_lower: "{{ email | lower }}"
price_cents: "{{ price_text | strip_currency }}"
joined: "{{ join_date | parse_date_dmy }}"

replace and regexp_replace take arguments:

fields:
clean_phone: '{{ phone | replace("+", "00") }}'
no_tags: '{{ body | regexp_replace("<[^>]+>", "") }}'
fields:
display_name: '{{ nickname ?? "Anonymous" }}'
fields:
tier: '{{ score > 0.7 ? "high" : "low" }}'

For column names with special characters, use double quotes inside the expression:

fields:
amount: '{{ "Debit/Credit" | to_number }}'
nodes:
enrich-orders:
type: data.map
config:
include_original: true
fields:
total: "{{ price * quantity }}"
discount_amount: "{{ total * discount_pct }}"
status_label: '{{ status == "paid" ? "Paid" : "Pending" }}'
nodes:
clean-contacts:
type: data.map
config:
fields:
name: "{{ first_name }} {{ last_name }}"
email: "{{ email | lower | trim }}"
score: "{{ raw_score | round }}"

Since include_original defaults to false, the output contains only name, email, and score.

nodes:
parse-amounts:
type: data.map
config:
include_original: true
fields:
amount: "{{ amount_text | strip_currency }}"
quantity: "{{ qty_string | to_number }}"
label: "{{ id | to_string }}"

Casts use TRY_CAST internally — unparseable values become null instead of errors.