Guides
Designing Metrics

Designing Metrics

Cube is a dataset-centric semantic layer, where all primary objects, cubes and views, are table-like datasets. When designing how your semantic layer will be exposed and consumed by end users, you can follow either entity-first approach or metrics-first. In both cases, views will be used to build the semantic layer interface.

Entity-first

In entity-first approach, views are built around entities in your data model. Views are built as denormalzied tables, bringing measures and dimensions from different cubes needed to fully decscribe the entity.

views:
  - name: orders_view
 
    cubes:
      - join_path: orders
        includes:
          - status
          - created_at
 
          - completed_count
          - count
          - total_amount
          - average_order_value
 
      - join_path: orders.users
        prefix: true
        includes: 
          - city
          - age
          - gender

In our example ecom project, these would be orders or line_items. In the example below we define orders_view view to describe orders entity. It has multiple measures and dimensions

You can optionally create multiple views to describe single entity. It can be useful for entities with a large number of dimensions to not overwhelm the end users with all the possible dimensions in a single view, but instead creating multiple slices of data with only relevant measures and dimensions.

In the example below, we are breaking down orders_view into orders_view and orders_with_users_view. Only the latter view will contain dimensions related to user who placed the order.

views:
  - name: orders_view
 
    cubes:
      - join_path: orders
        includes:
          - status
          - created_at
 
          - completed_count
          - count
          - total_amount
          - average_order_value
views:
  - name: orders_with_users_view
 
    cubes:
      - join_path: orders
        includes:
          - status
          - created_at
 
          - completed_count
          - count
          - total_amount
          - average_order_value
 
      - join_path: orders.users
        prefix: true
        includes: 
          - city
          - age
          - gender

Views are exposed as tables in Cube SQL API, dimensions can be queried as is

Metrics-first

In metrics-first approach, views are built around measures, or metrics, in your data model. Views are built as denormalzied tables, containing one measure and all the relevant dimensions from different cubes. These include all the dimensions you would group or filter by, and up to one time dimension.
Views are usually named after that single measure.

views:
  - name: average_order_value
 
    cubes:
      - join_path: orders
        includes:
          - average_order_value
 
          - status
          - created_at
 
      - join_path: orders.users
        prefix: true
        includes: 
          - city
          - age
          - gender
SELECT
  status,
  MEASURE(average_order_value)
FROM average_order_value
GROUP BY 1

NOTE: If a metric is interesting across more than one time dimension, create multiple views (metrics), one with each time dimension, and name the metric distinctly for each.
This approach improves compatibility with BI tooling and adds clarity for the consumer.

views:
  - name: order_count_by_order_date
 
    cubes:
      - join_path: orders
        includes:
          - order_count
 
          - status
          - created_at
 
  - name: order_count_by_ship_date
 
    cubes:
      - join_path: orders
        includes:
          - order_count
 
          - status
          - shipped_at

Integrations with BI Tools

Some metrics-based BI tools will specify requirements for the views or be able to accept additional metadata to enrich the experience.
Below is an example of using the meta property to do this.

views:
  - name: order_count_by_order_date
    description: For finance team to track orders on accrual/earned basis.
    meta:
      type: metric
      owner: alice@acme.com
 
    cubes:
      - join_path: orders
        includes:
          # MEASURE
          - order_count
 
          # TIME
          - created_at
 
          # DIMENSIONS
          - status
          - city