Appearance
Matching types
Every Context column in a definition has a Matching Type. Five options, applied independently per column, combined with pure AND across the definition. This is how range routing, conditional logic, and composite lookups all work.
There are no comparison operators inside column values, no IF statements, no boolean expressions. Conditionality is expressed entirely through Matching Type composition.
The five matching types
| Matching Type | Meaning |
|---|---|
| Exact | The document field's value equals the entity column's value (string compare). |
| Less Than | The entity column's value is less than the document field's value. |
| Less Than or Equal | The entity column's value is less than or equal to the document field's value. |
| More Than | The entity column's value is greater than the document field's value. |
| More Than or Equal | The entity column's value is greater than or equal to the document field's value. |
Each Context column gets its own Matching Type. A row matches the definition's lookup only if every Context column's comparison succeeds — pure AND.
Exact matching
The most common Matching Type. Used whenever the lookup is "find the row where this column equals that value."
Example: VendorId Exact against the Vendors entity. The document's VendorId=602362342 matches the entity row whose VendorId column is exactly 602362342. One row matches; its other columns push values back to the document.
Exact is a string compare — "100" and "100 " (with a trailing space) don't match. If you're seeing missed matches and the values look right, check for whitespace.
Range matching
The four numeric matching types — Less Than, Less Than or Equal, More Than, More Than or Equal — are how range routing works.
Example: an approver-routing definition has two Context columns:
SubTotalFromwith Matching Type Less Than or EqualSubTotalTowith Matching Type More Than or Equal
Combined with an entity whose rows look like:
| SubTotalFrom | SubTotalTo | approvers_1_1 | approvers_2_1 |
|---|---|---|---|
| -99999999 | 500 | manager@acmecorp.com | |
| 500 | 10000 | director@acmecorp.com | |
| 10000 | 999999999 | vp@acmecorp.com | ceo@acmecorp.com |
A document with SubTotal=247.15 finds row 1 (because -99999999 ≤ 247.15 AND 500 ≥ 247.15). The matched row's approvers_* columns push the approver list to the document.
This is how range routing gets expressed: by composing Matching Types on Context columns, not by encoding ranges inside column values.
Reading the operators
The verbal phrasing is from the entity's perspective: "Less Than" means "the entity's value is less than the document's value." Or equivalently, "the document's value is greater than the entity's value."
For range routing, the trick is to give every row a From (lower bound, matched as Less Than or Equal) and a To (upper bound, matched as More Than or Equal). The first column says "this row's lower bound is at or below the document's value"; the second says "this row's upper bound is at or above the document's value."
Composite matching
Multiple Context columns combine as pure AND. Every column's comparison must succeed for a row to match.
Example: a Header Products lookup with three Context columns:
customerInitialswith Matching Type ExactvendorAccountwith Matching Type ExactItem_erpItemDescriptionwith Matching Type Exact
A row matches only when all three of the document's current values exactly match the entity row's columns. Adding more Context columns narrows the lookup — fewer rows will match the increased specificity.
This is the typical pattern for granular lookups: start with broad context (customerInitials, vendorAccount) for cross-customer/cross-vendor lookups, then add a third column for per-item granularity.
Mixed matching
You can mix Exact and Range matching across Context columns:
customerInitialsExactcreditLimitMore Than 100000 (the entity row'screditLimitis more than 100,000)
The first column narrows to a specific customer; the second narrows to rows for customers with credit limits above a threshold. Composite AND across both.
What there isn't
A few things that aren't in the engine and aren't planned for the near-term:
- Equality with type coercion.
"100"(string) and100(number) don't match via Exact. Keep your data types consistent. - Substring match. No "starts with" or "contains" Matching Types.
- Pattern match. No regex.
- Not-equal. No "Exact NOT" or "Different From" Matching Type.
- OR within a single column. A Context column matches one value at a time; you can't say "match A or B."
For any of these needs, the typical workaround is multiple sequential rules in a workflow, each with different Context configurations.
Picking matching types
The decision tree:
- Looking up a row by an identifier? Exact. (Vendor by
VendorId, GL account byglCode, customer bycustomerNumber.) - Routing by a numeric range? Less Than or Equal on the lower-bound column, More Than or Equal on the upper-bound column.
- Narrowing within a context? Composite Exact on the discriminator columns plus whatever Matching Type fits the inner column.
If you find yourself wanting an operator that doesn't exist, the answer is almost always "split into multiple sequential rules in the workflow."
What's next
- Cascade behavior — how writes flow inside a workflow.
- The empty-cell rule — what happens when a matched row has empty cells.
- Context columns — how Matching Types attach to definitions.