AML Model Fields
Syntax for dimensions and measures inside a model.
Dimension
Dimension represents a column in a table or a calculation. You can combine dimensions in the current model into a new dimension.
Parameter definition
| Parameter name | Required | Description |
|---|---|---|
| label | Yes | User-friendly name for the dimension, shown to consumers. |
| type | Yes | Data type of the dimension. Possible values: 'text', 'number', 'date', 'datetime', 'truefalse', 'json', 'unknown'. |
| definition | No | How the dimension is calculated, using @sql or @aql syntax. If omitted, the compiler assumes a column with the same name exists in the underlying table. |
| description | No | Describes the semantic of the dimension. |
| hidden | No | Default false. Hides the dimension from consumers' field lists. This is not a security feature (Reason). |
| format | No | Display format for the dimension's value. See Number Format and Date Format. |
| primary_key | No | Default false. Marks this dimension as the primary key of the model. This enables query optimization and supports Single Model Conditions in AQL. Only one dimension per model should have primary_key: true. |
Definition of dimension
You can define dimensions using either @sql or @aql syntax. As a rule of thumb:
- Use
@sqlwhen referencing underlying table columns directly. - Use
@aqlfor calculations or transformations based on existing dimensions in the model (it provides better syntax suggestions, typechecking, and validation).
SQL definition
@sql {{ #SOURCE.column_name }};;: References a column in the table connected to the current model.@sql {{ dimension_name }};;: References another dimension defined within the same model.
Default behavior: If the definition for a dimension is not explicitly provided, the compiler assumes that there is a column in the underlying table with the same name as the dimension.
AQL definition
@aqldefinitions can reference existing dimensions in the current model using themodel.dimension_namesyntax.- Unlike
@sql, AQL definitions cannot reference underlying table columns directly (only dimensions that are already defined in the model).
Example of dimension syntax
Model orders {
type: 'table'
label: "Orders"
table_name: 'ecommerce.orders'
data_source_name: 'mydemodb'
description: "This is the AML Orders Model"
dimension id {
label: 'Order ID'
type: 'number'
primary_key: true // Mark as primary key for optimization and AQL features
definition: @sql {{ #SOURCE.id }};;
}
dimension status {
label: 'Status'
type: 'text'
//to reference the "status" column in the source table
definition: @sql {{ #SOURCE.status }};;
}
dimension created_at {
label: 'Created At'
type: 'datetime'
}
// AQL definition: references the existing "created_at" dimension
dimension created_at_year {
label: 'Created At Year'
type: 'number'
definition: @aql date_part('year', orders.created_at) ;;
}
}Measure
Measure represents an aggregation operation in a model.
Parameter definition
| Parameter name | Required | Description |
|---|---|---|
| label | Yes | User-friendly name for the measure, shown to consumers. |
| type | Yes | Data type of the measure's result. Possible values: 'text', 'number', 'date', 'datetime', 'truefalse', 'json', 'unknown'. Typically 'number'. |
| definition | Yes | How the measure is calculated. Use @aql (recommended) or @sql. Learn more below. |
| description | No | Describes the semantic of the measure. |
| hidden | No | Default false. Hides the measure from consumers' field lists. This is not a security feature (Reason). |
| aggregation_type | No | Default 'custom'. Aggregation kind: 'avg', 'sum', 'count', 'count distinct', 'min', 'max', 'median', 'stdev', 'stdevp', 'var', 'varp', 'running sum', 'running avg', 'running count', 'running min', 'running max', or 'custom' (when the definition itself is already an aggregation). |
| format | No | Display format for the measure's value. See Number Format and Date Format. |
AQL definition of measure
You can use either @sql or @aql to define measures, but we recommend using @aql for most cases as it provides better syntax suggestions, typechecking, and validation.
AQL provides built-in aggregation functions such as count(), sum(), avg(), min(), max(), count_distinct(), median(), and more. For a full list, see the Aggregation Functions reference.
Syntax forms: There are two equivalent ways to write an AQL aggregation:
-
Function call form (most common):
measure total_orders { label: 'Total Orders' type: 'number' definition: @aql count(orders.id) ;; } -
Pipe form:
measure total_orders { label: 'Total Orders' type: 'number' definition: @aql orders.id | count() ;; }
Both produce the same result. Use whichever feels more natural.
Referencing other measures: You can create derived measures by referencing other measures in the same model:
measure average_order_value {
label: 'Average Order Value'
type: 'number'
definition: @aql total_revenue / total_orders ;;
}You cannot use dimensions directly in a measure definition without wrapping them in an aggregation function. Every measure must produce an aggregated value.
Example of measure syntax
Model orders {
type: 'table'
label: "Orders"
table_name: 'ecommerce.orders'
data_source_name: 'demodb'
dimension id {
label: 'Order ID'
type: 'number'
primary_key: true
definition: @sql {{ #SOURCE.id }};;
}
dimension amount {
label: 'Amount'
type: 'number'
}
// Simple count aggregation
measure total_orders {
label: 'Total Orders'
type: 'number'
definition: @aql count(orders.id) ;;
}
// Sum aggregation
measure total_revenue {
label: 'Total Revenue'
type: 'number'
definition: @aql sum(orders.amount) ;;
}
// Derived measure referencing other measures
measure average_order_value {
label: 'Average Order Value'
type: 'number'
definition: @aql total_revenue / total_orders ;;
}
}FAQs
Should I use the 'hidden' property in dimension/measure for data restriction purposes?
The short answer is: you should not. hidden is a presentation hint, not an access rule. Access control belongs in the layer that serves the data, not in the model.
Use hidden: true when you want a dimension or measure to stay available for other definitions to reference, but kept out of the field list that consumers pick from.
dimension id {
label: 'Id'
type: 'number'
hidden: true
definition: @sql {{ #SOURCE.id }};;
}A hidden field is still a field. It can be referenced in a relationship, used in a filter, or named in any AQL expression, and anyone who can write AQL against the dataset can read it.
So hidden primarily serves to declutter the field list of your dataset. If certain users must not see certain fields, enforce that where the data is served, not with hidden.