ฐานความรู้ GetMyBot

Map fields and join lists

Extract nested fields, calculate values for each row, and combine two lists using a shared key.

บนหน้านี้

An order service returns the customer's name inside customer. You also need to multiply price by quantity and add class names from another list. Use two actions:

  • Map list fields (list_map) builds the fields you need in every row.
  • Join lists (list_join) adds fields from another list when their keys match.

These actions process data that has already been loaded. They do not call services or change collection records. For filtering, sorting and totals, see list operations.

Extract a name and calculate an amount

Suppose an earlier action saved this array as orders:

[
  {"id":"o1","customer":{"name":"Anna"},"price":1500,"quantity":2},
  {"id":"o2","price":2000,"quantity":1}
]

Choose orders as the source and save the result as prepared_orders. Add a field that copies the name, with a default for missing names, and a field that multiplies price by quantity:

{
  "source": "orders",
  "fields": [
    {"as":"guest_name","op":"copy","path":"customer.name","default":"No name"},
    {"as":"amount","op":"multiply","paths":["price","quantity"]}
  ],
  "keep_fields": false,
  "save_to_ctx": "prepared_orders"
}

The rows in prepared_orders.rows are:

[
  {"guest_name":"Anna","amount":3000},
  {"guest_name":"No name","amount":2000}
]

Enable keep_fields to retain ordinary source fields such as id, price and quantity. Genuine search metadata is retained separately; custom mappings cannot replace reserved metadata fields.

Available mapping operations

OperationopExample
Copy a fieldcopyRead customer.name
Set a constantliteralAdd a fixed source label
Combine textconcatCombine several scalar fields
AddaddPrice plus delivery
SubtractsubtractPrice minus discount
MultiplymultiplyPrice times quantity
DividedivideAmount divided by participant count

Use path for copying, paths for multiple operands, or value for a constant. Each mapping reads the original row. To use a field created by a mapping, add another action after this one.

Arithmetic follows operand order. Subtracting three fields means first minus second minus third. Decimal calculations preserve exact values: 0.1 × 3 is 0.3. Division rounds to 12 decimal places. Division by zero and values outside numeric limits produce an error.

The optional type converts the result to text, number or boolean. A numeric string such as "1500" can become a number. Boolean conversion accepts a boolean or the exact strings "true" and "false". Invalid values produce an error.

Nested paths and missing values

customer.name reads a nested object field. items.0.id reads the ID of the first array item; indexes start at zero.

For a literal key containing a dot, such as "customer.name", use the JSON Pointer /customer.name. Within a JSON Pointer key, write / as ~1 and ~ as ~0.

A default applies only when the field is missing. An explicit null is present and is not replaced. Copying a missing field without a default returns null. Arithmetic on a missing, null, empty or invalid number fails.

Add class names to bookings

The first list, bookings, contains:

[
  {"id":"b1","class_code":"wc","guest":"Anna"},
  {"id":"b2","class_code":"clay","guest":"Boris"},
  {"id":"b3","class_code":"photo","guest":"Vera"}
]

The second list, classes, contains:

[
  {"code":"wc","name":"Watercolour"},
  {"code":"clay","name":"Clay modelling"}
]

Use class_code as the left key and code as the right key. Keep every booking and prefix added fields with details_:

{
  "source": "bookings",
  "right_source": "classes",
  "left_key": "class_code",
  "right_key": "code",
  "mode": "left",
  "multiple": "error",
  "right_prefix": "details_",
  "save_to_ctx": "joined_bookings"
}

Anna's row receives details_name="Watercolour"; Boris's receives details_name="Clay modelling". Vera's booking remains without added fields because there is no photo class in the right list.

Choose a prefix that does not collide with existing fields. For example, class_ plus the right field code would collide with the left field class_code. A collision produces an error instead of overwriting data.

Right-side metadata fields _record_id, _score and _match_type are not added: the result row still represents the left record. If you need the right record's ID, first use Map list fields to copy its _record_id into an ordinary field such as class_record_id. After joining, it is available with your prefix, for example details_class_record_id.

Missing and duplicate keys

SettingBehaviour
mode=leftKeep every left row, including rows without a match
mode=innerKeep only rows with a match
multiple=errorFail when a left key matches multiple right rows
multiple=firstUse the first matching right row
multiple=allProduce a separate row for each matching right row

With all, two bookings matching three right rows produce six output rows. The output still has to fit the row and byte limits.

Missing keys and null never match. An empty string "" is a valid text key and matches another empty string; filter those rows first if you do not want this. Types matter: number 1 differs from string "1". Objects and arrays cannot be join keys. Numeric keys are compared exactly, including large identifiers; service IDs are usually easiest to keep as strings.

Left row order is preserved. Multiple right matches keep their original order. Use first only when the right list's order is meaningful.

Completeness, limits and testing

Each input and the output allow up to 10,000 rows. The two join inputs together must fit within 16 MiB. The output is also bounded by size. A mapping allows up to 256 field definitions. Exceeding a limit fails explicitly instead of silently dropping rows.

An action also has a budget of 1,000,000 work units, based on row counts, mappings, operands and path depth. Join work includes output rows and fields. This budget is checked before expensive evaluation. Reduce the input, unused fields or operand count if a transformation is too complex. Cancellation stops processing.

The 16 MiB output limit reserves 512 bytes for envelope metadata. A row that almost fills the limit may therefore be too large. Intermediate strings and expanded join output are bounded before being retained in memory.

If either source is incomplete, the joined result remains incomplete. A missing match in the loaded right list does not prove that the full collection has no matching record.

Literal JSON previews process only supplied data. They do not run the reaction, call external services or write records. Use the draft check to check the complete unsaved flow with sample data: load data, transform it, then prepare a button or message. After saving, verify the flow through your connected bot and channel. That run executes the saved actions and can call services or change records.

Check four cases: a normal row, a missing nested field, duplicate right keys, and an incomplete source. Verify row order, counts and completeness.

Related material: list operations, collections, practical exercises.