Metric Queries
Metric Queries allow users to request data from semantic models by specifying metrics, dimensions, filters, and time ranges. The Semantic Layer compiles these high-level requests into optimized SQL and executes them against the Query Engine. This abstraction eliminates the need for users to write SQL directly while ensuring queries are consistent with the defined business logic.
Query Structure
A metric query specifies what to compute and how to slice the results.
| Field | Type | Required | Description |
|---|---|---|---|
modelId | UUID | Yes | Semantic model to query |
metrics | List | No | Metric names to compute |
dimensions | List | No | Dimensions to group by |
filters | List | No | Filter conditions |
orderBy | List | No | Sort order |
timeDimension | String | No | Time dimension for temporal queries |
timeGrain | String | No | Temporal granularity (DAY, WEEK, MONTH, QUARTER, YEAR) |
timeRangeStart | Instant | No | Start of time range |
timeRangeEnd | Instant | No | End of time range |
relativeTimeRange | String | No | Relative time expression (e.g., "last 30 days") |
limit | Integer | No | Maximum rows to return |
offset | Integer | No | Row offset for pagination |
useCache | Boolean | No | Whether to use cached results |
timeoutSeconds | Integer | No | Query timeout |
Example Query
{
"modelId": "550e8400-e29b-41d4-a716-446655440000",
"metrics": ["total_revenue", "order_count"],
"dimensions": ["region", "order_date"],
"filters": [
{
"field": "region",
"operator": "IN",
"values": ["US", "EU"]
},
{
"field": "order_total",
"operator": ">=",
"value": 100
}
],
"orderBy": [
{
"field": "total_revenue",
"descending": true
}
],
"timeDimension": "order_date",
"timeGrain": "MONTH",
"timeRangeStart": "2026-01-01T00:00:00Z",
"timeRangeEnd": "2026-12-31T23:59:59Z",
"limit": 100
}Filter Operators
| Operator | Description | Example |
|---|---|---|
= | Equals | region = 'US' |
!= | Not equals | status != 'cancelled' |
> | Greater than | amount > 100 |
>= | Greater than or equal | amount >= 100 |
< | Less than | amount < 1000 |
<= | Less than or equal | amount <= 1000 |
IN | In list | region IN ('US', 'EU') |
NOT_IN | Not in list | status NOT_IN ('cancelled', 'refunded') |
LIKE | Pattern match | name LIKE '%smith%' |
IS_NULL | Is null | email IS NULL |
IS_NOT_NULL | Is not null | email IS NOT NULL |
BETWEEN | Range | amount BETWEEN 100 AND 1000 |
Query Compilation
The compilation process transforms a semantic query into executable SQL.
| Step | Description |
|---|---|
| 1 | Resolve model and verify metrics/dimensions exist |
| 2 | Build SELECT clause from metrics (with aggregation) and dimensions |
| 3 | Build FROM clause using the model table reference |
| 4 | Traverse relationships and add JOINs for cross-model references |
| 5 | Build WHERE clause from filters |
| 6 | Build GROUP BY clause from dimensions |
| 7 | Build ORDER BY clause |
| 8 | Apply LIMIT and OFFSET |
| 9 | Pass compiled SQL through the query optimizer |
Query Result Structure
{
"data": [
{
"region": "US",
"order_date": "2026-01",
"total_revenue": 1250000.00,
"order_count": 4520
}
],
"columns": [
{
"name": "region",
"type": "VARCHAR",
"displayName": "Region",
"isDimension": true,
"isMetric": false,
"nullable": false
},
{
"name": "total_revenue",
"type": "DECIMAL",
"displayName": "Total Revenue",
"isDimension": false,
"isMetric": true,
"nullable": true
}
],
"totalRows": 24,
"executionTimeMs": 342,
"fromCache": false,
"sql": "SELECT ... FROM ... WHERE ... GROUP BY ..."
}Time Grain Options
| Grain | Description |
|---|---|
DAY | Daily aggregation |
WEEK | Weekly aggregation |
MONTH | Monthly aggregation |
QUARTER | Quarterly aggregation |
YEAR | Yearly aggregation |
Saved Queries
Users can save frequently used metric queries for reuse.
| Field | Description |
|---|---|
name | Query name (required, max 256 characters) |
description | Description of the query |
isPublic | Whether other tenant users can see the saved query |
compiledSql | The compiled SQL stored for reference |
executionCount | Number of times the query has been executed |
lastExecutedAt | Timestamp of the last execution |
Caching
Metric queries support result caching. When useCache is set to true, the Semantic Layer checks for cached results before compiling and executing the query. Cache keys are derived from the query parameters and tenant context.