Configure field-mapping expressions

Prev Next

Normalize vendor fields with a closed pipe DSL on fieldMappings.attributes. One value in, one value out. Use split then index when you need one array element — not a hardcoded character offset.

Attribute shape, identity, and dimensions stay on Configure business vocabulary. This page is the expression catalog the CIP map step runs.

Prerequisites

  • Datasource JSON with fieldMappings.attributes and matching metadataSchema.properties
  • Configure data flow — list/get operations use a map step
  • Login and aifabrix datasource validate rights for the Connected System

Where it lives

Layer Location
Read expression <datasourceKey>.json → fieldMappings.attributes.<name>.expression
CIP map execution.cip.operations.*.steps → map.useFieldMappings (default true) or map.inline
Display label Root labelKey (joins present fields with a space)

Short-form sugar is a string equal to a {{...}} expression; the compiler expands it to { "expression": "..." }.

How to set

  1. Start from a root — {{raw.<path>}}, or one hop {{fk.<name>.metadata.<field>}} / {{dimension.<key>}}.
  2. Pipe functions with |. The left side is the pipeline value; extra arguments go in parentheses.
  3. Pick an array element with index after split (0-based; negative counts from the end). Strings stay substring — index does not treat a string as characters.
{
  "fieldMappings": {
    "attributes": {
      "status": {
        "expression": "{{raw.fields.state}} | toLower | trim"
      },
      "folderLabel": {
        "expression": "{{raw.driveItem.parentReference.path}} | coalesce(raw.parentReference.path) | split('root:/') | index(1)",
        "description": "Library-relative folder after the document-root marker"
      }
    }
  }
}
  1. If the field is on labelKey, add it to metadataSchema.properties with index: true.
  2. Validate (see below). Function chains are non-invertible: they default to direction: "read" unless you set writePath.

Unknown names such as nth fail compile (unknown_function). Missing, non-array, empty, or out-of-range index returns null (same fail-soft as the rest of the DSL).

Defaults and examples

Closed allow-list (11 functions). join and split default delimiter is , (comma), not empty string or whitespace.

Function Arguments Effect
toLower / toUpper / trim / normalizeWhitespace (value) Case and whitespace
substring (value, start [, end]) Slice a string; negative start from the end
replace (value, search, replacement) Replace all occurrences
default (value, defaultValue) Fallback when null/empty
coalesce (value, ...) First non-null/non-empty
join (value [, delimiter]) Array → string; default ","
split (value [, delimiter]) String → array; default ","
index (value, n) Array element; 0-based n; negative from the end

Example: path /drives/<id>/root:/Deals/Roche with split('root:/') | index(1) yields Deals/Roche. Pair labelKey: ["folderLabel", "name"] for a space-joined operator label. There is no concat in this catalog — a dashed separator is a later mapping, not CIP pythonInline for a one-element pick.

Validate

aifabrix datasource validate <datasourceKey>
aifabrix validate <systemKey>

Expect compile errors for unknown functions or wrong argument counts. After publish, list records and confirm display uses labelKey fields.

Common mistakes

Mistake Fix
"source": "$.id" JSONPath Use "expression": "{{raw.id}}"
substring(N) for a variable-length drive id split('root:/') \| index(1)
index on a string Use substring; index is arrays only
Inventing nth, at, concat, or regex Stay on the closed list; unknown names fail compile
Assuming split defaults to whitespace Default delimiter is ","
Putting pythonInline on a one-element pick Use index in the map DSL

Limits

The allow-list is closed: no JMESPath inside fieldMappings, no format helpers, and no growing the registry per vendor. CIP pythonInline remains last resort for transforms the pipe cannot express. labelKey still joins with a space.