Expressions
CXTMS provides a powerful expression system for sorting, filtering, and querying data through the GraphQL API and workflow variable resolution. These expressions allow you to dynamically control how data is retrieved, ordered, and accessed without writing custom queries.
Capabilities
| Feature | Description |
|---|---|
| Sorting | Order results by any entity property, including nested properties and custom values |
| Filtering | Filter results using Lucene query syntax with support for wildcards, ranges, and boolean logic |
| Join Syntax | Sort and filter by properties of related entities through custom value foreign keys |
| Type-Aware Sorting | Cast custom value strings to date, numeric, or boolean types for correct sort order |
| Collection Filtering | Filter within nested collections using bracket syntax |
| Business Date Math | Use BHOUR and BDAY tokens in filter expressions to calculate business hours and days |
| Optional Property Access | Append ? to a property path segment to return null instead of throwing an error when the property is missing |
Quick Examples
Sorting
# Sort by name ascending
orderBy: "name"
# Sort by creation date descending
orderBy: "-created"
# Sort by multiple fields
orderBy: "status,-created"
# Sort by custom value with type cast
orderBy: "customValues.ETA~date"
# Sort by a joined entity property
orderBy: "customValues.carrierId->contact.name"
Filtering
# Filter by exact value
filter: "status:Active"
# Wildcard search
filter: "name:*express*"
# Range filter
filter: "created:[2024-01-01 TO 2024-12-31]"
# Boolean logic
filter: "(status:Active OR status:Pending) AND priority:High"
# Filter by joined entity
filter: "customValues.carrierId->contact.name:Acme*"
Optional Property Access
Append a ? suffix to any property path segment to make it nullable. When a property path includes ?, the expression returns null instead of throwing an InvalidOperationException if the property or variable does not exist.
# Required — throws if 'carrier' is missing
carrier.name
# Optional — returns null if 'carrier' is missing
carrier?.name
This is especially useful in workflow task contexts where inputs may be optional. The nullable context methods (ToObjectN, ToObjectEnhancedN, TryGetObject) automatically apply the ? suffix when resolving task variables, so workflow tasks that read optional inputs will receive null rather than a runtime exception when the variable is not defined.
# In a workflow task, 'columnMappings' is an optional input.
# The task handler calls ToObjectN("columnMappings"), which internally
# resolves as "columnMappings?" — returning null if not provided.
inputs:
columnMappings:
type: object
required: false
Special Values in Data Contexts
When supplying data to workflow tasks or entity changes, certain string values carry reserved meaning beyond their literal content.
$delete — remove sentinel
Assigning the exact string "$delete" to a key instructs the system to remove that key from the target dictionary rather than setting it to any value. This is used, for example, when clearing a custom value field via Entity/Change@1.
customValues:
fieldToRemove: "$delete" # key is deleted from the entity
fieldToKeep: "newValue" # key is set normally
The sentinel is exact-match and case-sensitive: $DELETE, $delete (with a space), or $delete extra are stored as ordinary strings, not treated as removal instructions. It also applies only to top-level string values — "$delete" nested inside a list or sub-object has no special effect.
Related Topics
- Sorting Expressions - Full sorting syntax reference
- Filter Expressions - Lucene-based filter syntax reference
- Join Expressions - Sort and filter by related entity properties
- Entity Change Tasks - Modifying entity custom values in workflow tasks