Skip to content

Commit

Permalink
docs: draft of designing metrics guide
Browse files Browse the repository at this point in the history
  • Loading branch information
keydunov committed Dec 1, 2023
1 parent 8649bec commit 2740da4
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/pages/guides/_meta.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
"dbt": "Using Cube with dbt",
"designing-metrics": "Designing Metrics",
"recipes": "Recipes",
"style-guide": "Style guide",
"data-store-cost-saving-guide": "Cost saving guide"
Expand Down
118 changes: 118 additions & 0 deletions docs/pages/guides/designing-metrics.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# 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.

```yaml
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.

```yaml
views:
- name: orders_view
cubes:
- join_path: orders
includes:
- status
- created_at
- completed_count
- count
- total_amount
- average_order_value
```

```yaml
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.
Views are usually named after that single measure.

```yaml
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
```


```sql
SELECT
status,
MEASURE(average_order_value)
FROM average_order_value
GROUP BY 1
```

0 comments on commit 2740da4

Please sign in to comment.