Sorting Expressions
The orderBy parameter on GraphQL queries accepts a comma-separated list of sort expressions. Each expression targets a property path and optionally specifies sort direction, type casting, or join syntax.
Basic Syntax
orderBy: "propertyName" # ascending (default)
orderBy: "-propertyName" # descending (prefix with -)
orderBy: "field1,-field2" # multi-field: first ascending, then descending
The first field uses OrderBy / OrderByDescending; subsequent fields use ThenBy / ThenByDescending.
Nested Properties
Dot notation navigates into nested objects and collections:
orderBy: "contact.name"
orderBy: "-route.departureDate"
When a property in the path is a collection, the system automatically selects the first element (FirstOrDefault) before continuing navigation.
Custom Value Sorting
Entities with a customValues dictionary (JSONB column) support sorting by custom field keys:
orderBy: "customValues.invoiceNumber"
This extracts the value as text using JsonbExtractPathText. Since all custom values are stored as strings, text-based sort order applies by default.
Type-Aware Sorting
Append ~type to cast the extracted value before sorting:
orderBy: "customValues.ETA~date" # cast to date
orderBy: "customValues.weight~numeric" # cast to numeric
orderBy: "customValues.isActive~boolean" # cast to boolean
| Type | Method | Use Case |
|---|---|---|
date | JsonbExtractPathDate | Date/datetime strings (ISO 8601) |
numeric | JsonbExtractPathNumeric | Numbers stored as strings |
boolean or bool | JsonbExtractPathBoolean | Boolean values stored as strings |
Comparison-Based Sorting
Append :value to sort by whether a field equals a specific value (boolean result):
orderBy: "status:Active"
This produces a boolean sort key (true where status == "Active", false otherwise), useful for pinning specific rows to the top or bottom.
The colon delimiter is only recognized outside of bracket expressions. Inside collection[filter:value] bracket syntax, colons are treated as part of the filter.
Collection Filter Sorting
Sort by a property within a filtered subset of a collection:
orderBy: "children[category:Import].amount"
This applies a Where filter to the children collection (keeping only items where category == Import), then sorts by the amount property of the first matching element.
Join Sort Syntax
Sort by a property on a related entity referenced through a custom value foreign key. See Join Expressions for full details.
orderBy: "customValues.carrierId->contact.name"
orderBy: "-customValues.countryCode->country.name"
Descending Sort Behavior
For numeric types, descending sort is implemented by negating the value and using ascending order. For non-numeric types (strings, dates, booleans), the system uses OrderByDescending / ThenByDescending.
Error Handling
Invalid sort fields produce a ValidationException with details about which field failed. Multiple sort fields are validated independently; all errors are collected and returned together.
GraphQL Usage
Sorting is available on any paginated query that accepts an orderBy parameter:
query {
orders(
organizationId: 1
orderBy: "-created,status"
limit: 50
) {
items {
orderId
created
status
}
totalCount
}
}
Related Topics
- Filter Expressions - Lucene-based filter syntax
- Join Expressions - Sort and filter by related entities
- Custom Fields - Custom value storage and naming