Decision Tables
Overview
Decision tables can replace complicated conditional logic with simple matrices. They can also be used to decouple business/decisioning logic from application code and make it accessible to non-technical users. Decision tables are an alternative to decision trees.
Evaluate a Simple Decision Table
This standalone example demonstrates the logic for a very simple loan eligibility check logic that can be added to any app. It contains three input fields (Age, House Owned, and Income) and one output field (Eligible).
# | Conditions | Outcome | ||
---|---|---|---|---|
Age | House Owned | Income | Eligible | |
1 | ? >= 40 | ? == true | true | |
2 | ? >= 40 | ? == false | ? >= 2000 | true |
3 | ? >= 40 | ? == false | ? < 2000 | false |
4 | ? < 40 | ? >= 3000 | true | |
5 | ? < 40 | ? < 3000 | false |
Each row represents a separate rule. Rules are evaluated sequentially, one-at-a-time from top to bottom, until a rule is found where all its conditions are true. Processing stops at that point and the outcome fields are returned.
Both the condition and outcome cells are specified using the DataPipeline Expression Language. Each column represents a different field. Conditional expressions have the option of using a question mark in place of their variable name. For example, all of the following expressions are legal:
- ? >= 40
- Age >= 40
- ${Age} >= 40
A few things to keep in mind:
- If a field's name is used, it must be surrounded with ${} if it contains a space or symbol. For example, "House Owned" would have to be wrapped: ${House Owned}.
- Cells without an expression are skipped.
- A decision table can contain multiple condition and multiple outcome columns
Example: EvaluateADecisionTable.java
Add a Calculated Field to a Decision Table
Decision tables allow you to replace repeating values and expressions throughout with a single, shared value or expression. This example shows how to add constants (ageThreshold
) and expressions (overAgeThreshold
) for use in conditions and outcomes.
Example: AddCalculatedFieldsToADecisionTable.java
Evaluate a Decision Table in a DataPipeline Job
Decision tables are very useful on their own, but they can also be added to any DataPipeline job. This example shows how to add a decision table to a job that reads a CSV file. It also shows how to:
- Add multiple outcome fields (Total and Product Type).
- Turn outcome fields into calculated expressions (${Variant Price} + Shipping).
- Add calculated fields for use throughout a decision table (Variant Price).
Example: AddADecisionTableToAPipeline.java
Add a Lookup to a Decision Table
Decision tables can also use the lookup functions in the expression language to map one value to another from a database, file, or API. This example uses a programmatic lookup to find currency names for their codes in the outcome expression of decision table rules.
Example: EvaluateADecisionTableWithLookup.java
Run an Action when a Decision Table Rule Fires
Sometimes the outcome of a decision rule firing should be an action. This example shows how to call an arbitrary function when a rule fires.
Here are a few things to keep in mind:
- The example contains two static functions:
action1()
andaction2(int age, double income)
. - A simple
action2
alias is created for the second function, otherwise, it's fully-qualified name would have to be used. - Outcomes always require a field name, even if their expression calls a void function.
- Input fields can be used in the outcome and passed to user-defined functions.
Example: ExecuteAnActionInADecisionTable.java
Save a Decision Table to/from XML
This example saves a programmatically built decision table to XML and loads it back. This allows you to store decision tables as program resources on disk or in a database. It also allows you to modify them programmatically and save them back to disk.
Example: SaveAndLoadDecisionTableToXML.java
The generated XML for the above decision table would be the following.
Expression Language Built-In Variables
Variable | Description | Example |
---|---|---|
rownum | The current row number, starting at 1. | rownum % 2 == 0 |