Semantics

Dimensions

Categorical attributes for grouping and analyzing measures, representing the ways you slice and dice your data.

Diagram showing how dimensions enable data grouping and filtering

Use Cases

Dimensions are used for:

  • Geographic Analysis: Group by country, region, city
  • Time-based Analysis: Group by date, month, quarter, year
  • User Segmentation: Group by user type, subscription tier, demographics
  • Product Analysis: Group by category, brand, price range
  • Performance Analysis: Group by device, browser, operating system

Syntax

Type: SemanticDimension

List of categorical attributes by which the measures can be grouped. Dimensions define how data should be categorized and filtered.

{
    "dimensions": [
        {
            "name": "user_segment",
            "description": "User segmentation category",
            "query": "segment_type",
            "table": "users",
            "formatting": [
                {
                    "name": "segment_display",
                    "type": "format",
                    "format_type": "custom",
                    "format_string": "Segment: {value}"
                }
            ]
        }
    ]
}

Parameters

name

Type: str
Required: Yes

Unique identifier name for this dimension. Used to reference the dimension in queries and API calls.

{
    "name": "user_segment"
}

description

Type: Optional[str]
Default: None
Required: No

Human-readable explanation of what this dimension represents. Helps other developers understand the categorization logic.

{
    "description": "User segmentation based on subscription tier and usage patterns"
}

query

Type: str
Required: Yes

Column name or SQL expression that defines this dimension. Used in query generation to specify the data field for grouping.

{
    "query": "segment_type"
}

table

Type: Optional[str]
Default: None
Required: No

Source table or view where this dimension's data resides. Specifies the primary data source for the dimension.

{
    "table": "users"
}

formatting

Type: Optional[List[OutputFormat]]
Default: None
Required: No

Array of OutputFormat objects for display transformation. Allows you to format dimension values for better presentation.

{
    "formatting": [
        {
            "name": "segment_display",
            "type": "format",
            "format_type": "custom",
            "format_string": "Segment: {value}"
        }
    ]
}

combine

Type: Optional[List[CombineColumnSpec]]
Default: None
Required: No

Array of additional columns to combine with the dimension, concatenating multiple columns into a single value. Useful for combining related fields like first and last names, or address components.

Each CombineColumnSpec has:

  • query: Column name or expression to combine
  • table: Source table (optional, if different from dimension's table)
  • delimiter: Separator to use before this column (default: space)
{
    "name": "full_name",
    "description": "Combined first and last name",
    "query": "first_name",
    "table": "users",
    "combine": [
        {
            "query": "last_name",
            "table": "users",
            "delimiter": " "
        }
    ]
}

Generated SQL:

CONCAT(first_name, ' ', last_name) AS "full_name"

conditional

Type: bool
Default: False
Required: No

Boolean flag indicating whether to use conditional logic (CASE WHEN statements) instead of the simple query field.

{
    "conditional": true
}

conditions

Type: Optional[Condition]
Default: None
Required: No

A Condition object defining CASE WHEN logic for dynamic categorization.

{
    "conditional": true,
    "conditions": {
        "when_clauses": [...],
        "else_return": "..."
    }
}

Column Combination

Dimensions can combine multiple columns into a single value using the combine field. This is useful for concatenating related fields.

Example 1: Full Name from First and Last

{
    "name": "full_name",
    "description": "Customer full name",
    "query": "first_name",
    "table": "users",
    "combine": [
        {
            "query": "last_name",
            "table": "users",
            "delimiter": " "
        }
    ]
}

Generated SQL:

CONCAT(users.first_name, ' ', users.last_name) AS "full_name"

Example 2: Full Address

{
    "name": "full_address",
    "description": "Complete address",
    "query": "street_address",
    "table": "addresses",
    "combine": [
        {
            "query": "city",
            "delimiter": ", "
        },
        {
            "query": "state",
            "delimiter": ", "
        },
        {
            "query": "zip_code",
            "delimiter": " "
        }
    ]
}

Generated SQL:

CONCAT(
    street_address, ', ', 
    city, ', ', 
    state, ' ', 
    zip_code
) AS "full_address"

Example 3: Date and Time Combination

{
    "name": "timestamp",
    "description": "Combined date and time",
    "query": "event_date",
    "table": "events",
    "combine": [
        {
            "query": "event_time",
            "delimiter": " "
        }
    ]
}

Conditional Logic

Dimensions support conditional logic for dynamic categorization based on values.

Example: Revenue Bucket Classification

Categorize orders by amount:

{
    "name": "Order Size",
    "description": "Order size category",
    "conditional": true,
    "conditions": {
        "when_clauses": [
            {
                "field": {
                    "column": "order_amount",
                    "table": "orders"
                },
                "operator": "<",
                "compare_values": 100,
                "then_return": "Small"
            },
            {
                "field": {
                    "column": "order_amount",
                    "table": "orders"
                },
                "operator": "<",
                "compare_values": 1000,
                "then_return": "Medium"
            }
        ],
        "else_return": "Large"
    }
}

Generated SQL:

CASE
  WHEN orders.order_amount < 100 THEN 'Small'
  WHEN orders.order_amount < 1000 THEN 'Medium'
  ELSE 'Large'
END AS "Order Size"

Combining Conditional Logic with Column Combination

You can use conditional logic with the combine feature. The conditional logic is applied after column combination:

{
    "name": "Customer Tier",
    "description": "Customer tier based on combined score",
    "conditional": true,
    "conditions": {
        "when_clauses": [
            {
                "field": {
                    "column": "score",
                    "table": "customers"
                },
                "operator": ">",
                "compare_values": 1000,
                "then_return": "Premium"
            }
        ],
        "else_return": "Standard"
    }
}

For complete details on building conditional statements, see the Conditional Logic Architecture.

Patterns

Geographic Dimensions

{
    "dimensions": [
        {
            "name": "country",
            "description": "User country",
            "query": "country_code",
            "table": "users"
        },
        {
            "name": "region",
            "description": "Geographic region",
            "query": "CASE WHEN country_code IN ('US', 'CA', 'MX') THEN 'North America' ELSE 'Other' END",
            "table": "users"
        }
    ]
}

Time Dimensions

{
    "dimensions": [
        {
            "name": "year",
            "description": "Order year",
            "query": "EXTRACT(YEAR FROM created_at)",
            "table": "orders"
        },
        {
            "name": "month",
            "description": "Order month",
            "query": "TO_CHAR(created_at, 'YYYY-MM')",
            "table": "orders"
        },
        {
            "name": "day_of_week",
            "description": "Day of the week",
            "query": "TO_CHAR(created_at, 'Day')",
            "table": "orders"
        }
    ]
}

User Segmentation

{
    "dimensions": [
        {
            "name": "user_tier",
            "description": "Subscription tier",
            "query": "subscription_tier",
            "table": "users",
            "formatting": [
                {
                    "name": "tier_display",
                    "type": "format",
                    "format_type": "custom",
                    "format_string": "{value} Tier"
                }
            ]
        },
        {
            "name": "age_group",
            "description": "User age group",
            "query": "CASE WHEN age < 25 THEN '18-24' WHEN age < 35 THEN '25-34' ELSE '35+' END",
            "table": "users"
        }
    ]
}

Product Categories

{
    "dimensions": [
        {
            "name": "product_category",
            "description": "Product category",
            "query": "category_name",
            "table": "products"
        },
        {
            "name": "price_range",
            "description": "Price range",
            "query": "CASE WHEN price < 50 THEN 'Budget' WHEN price < 200 THEN 'Mid-range' ELSE 'Premium' END",
            "table": "products"
        }
    ]
}

Advanced Techniques

Calculated Dimensions

Create dimensions based on complex calculations:

{
    "name": "customer_lifetime_value_tier",
    "description": "Customer value tier based on total spend",
    "query": "CASE WHEN total_spend > 10000 THEN 'High Value' WHEN total_spend > 1000 THEN 'Medium Value' ELSE 'Low Value' END",
    "table": "customers"
}

Hierarchical Dimensions

Create parent-child relationships:

{
    "dimensions": [
        {
            "name": "region",
            "description": "Geographic region",
            "query": "region_name",
            "table": "locations"
        },
        {
            "name": "country",
            "description": "Country within region",
            "query": "country_name",
            "table": "locations"
        },
        {
            "name": "city",
            "description": "City within country",
            "query": "city_name",
            "table": "locations"
        }
    ]
}

Best Practices

  1. Use Clear Naming: Choose descriptive names that clearly indicate what the dimension represents
  2. Add Descriptions: Always include descriptions to explain the categorization logic
  3. Consider Cardinality: Be mindful of high-cardinality dimensions that might create too many groups
  4. Use Formatting: Apply appropriate formatting for better data presentation
  5. Optimize Queries: Use efficient column references and avoid complex calculations when possible

Performance

  • Indexing: Ensure dimension columns are properly indexed for fast grouping
  • Cardinality: High-cardinality dimensions can impact query performance
  • Data Types: Use appropriate data types for better storage and query efficiency

Video Tutorial

Video: How to set up and configure dimensions in the Cortex dashboard

Dashboard Examples

Example showing how dimensions appear in the Cortex dashboard interface