cube-js / cube-js/cube

Difficulty Adding Computed Metrics in Cube.js

Open
#8,528 0 comments 0 reactions 1 assignee Claimed by @igorlukanin View on GitHub
question
Dominant language
Rust
Stars
20.8k
Forks
2.1k
Avg merge
1d 2h
Merged PRs (30d)
181

Description

Hello,

I am encountering an issue while trying to add computed metrics in my Cube.js schema. I currently have a functioning schema that looks like this:

```javascript
cube(`fct_users_progress_statuses`, {
sql: `SELECT * FROM users_progress`,
preAggregations: {
main: {
measures: [
fct_users_progress_statuses.sum_total_lessons_completed,
fct_users_progress_statuses.sum_total_lessons,
fct_users_progress_statuses.total_users,
],
dimensions: [
fct_users_progress_statuses.sk_dim_organizations,
fct_users_progress_statuses.sk_dim_courses,
fct_users_progress_statuses.sk_dim_users,
],
timeDimension: fct_users_progress_statuses.datetime_created_at,
granularity: `day`,
partitionGranularity: `month`
},
},
joins: {
organizations: {
sql: `${CUBE}.sk_organizations = {organizations}.sk_organizations`,
relationship: `many_to_one`,
},
users: {
sql: `${CUBE}.sk_users = {users}.sk_users`,
relationship: `many_to_one`,
},
courses: {
sql: `${CUBE}.sk_courses = {courses}.sk_courses`,
relationship: `many_to_one`,
},
},
measures: {
sum_total_lessons_completed: {
sql: `value_total_lessons_completed`,
type: `sum`,
},
sum_total_lessons: {
sql: `value_total_lessons`,
type: `sum`,
},
percentage_progress_employees: {
sql: `(${sum_total_lessons_completed} / CAST(NULLIF(${sum_total_lessons}, 0) AS DOUBLE)) * 100`,
type: `number`,
},
total_users: {
sql: `(${sk_users_progress})`,
type: `count`,
},
},
dimensions: {
sk_users_progress: {
sql: `sk_users_progress`,
type: `string`,
primaryKey: true,
},
sk_dim_users: {
sql: `sk_dim_users`,
type: `string`,
},
sk_dim_organizations: {
sql: `sk_dim_organizations`,
type: `string`,
},
sk_dim_courses: {
sql: `sk_dim_courses`,
type: `string`,
},
datetime_created_at: {
sql: `datetime_created_at`,
type: `time`,
},
},
});
```

This schema works well when I execute the following cube.load:

```javascript
cubeApi.load({
measures: ['fct_users_progress_statuses.percentage_progress_employees'],
dimensions: ['fct_users_progress_statuses.sk_dim_users'],
timeDimensions: [{
dimension: 'fct_users_progress_statuses.datetime_created_at',
dateRange: ['2024-01-01', '2024-06-30'],
}]
});
```

However, I would like to add three new metrics that are calculated based on the progress:

- percentage_complete_contents
- percentage_in_progress_contents
- percentage_unstarted_contents

I implemented them as follows:

```javascript
total_complete_contents: {
title: `Total complete contents`,
type: `count`,
filters: [
{
sql: (CUBE) => `${CUBE.percentage_progress_employees} = 100`,
},
],
},
percentage_complete_contents: {
title: `Percentage complete contents`,
type: `number`,
format: `percent`,
sql: (CUBE) => `ROUND(${CUBE.total_complete_contents} / ${CUBE.total_users} * 100.0, 2)`,
},
total_in_progress_contents: {
title: `Total in progress contents`,
type: `count`,
filters: [
{
sql: (CUBE) => `${CUBE.percentage_progress_employees} > 0 AND ${CUBE.percentage_progress_employees} < 100`,
},
],
},
percentage_in_progress_contents: {
title: `Percentage in progress contents`,
type: `number`,
format: `percent`,
sql: (CUBE) => `ROUND(${CUBE.total_in_progress_contents} / ${CUBE.total_users} * 100.0, 2)`,
},
total_unstarted_contents: {
title: `Total unstarted contents`,
type: `count`,
filters: [
{
sql: (CUBE) => `${CUBE.percentage_progress_employees} = 0`,
},
],
},
percentage_unstarted_contents: {
title: `Percentage unstarted contents`,
type: `number`,
format: `percent`,
sql: (CUBE) => `ROUND(${CUBE.total_unstarted_contents} / ${CUBE.total_users} * 100.0, 2)`,
},
```

Unfortunately, I encounter an error: `Type.Error: sql.match is not a function.`
![image](https://github.com/user-attachments/assets/88ca050a-fbe2-4886-9738-20caa27eb6c4)

Currently, I am calculating these metrics on the backend by executing cube.load, retrieving the data, and then returning the three measures. However, I am facing a limitation of 50k records and I would prefer not to proceed in this manner. I would like suggestions on how to add these metrics directly in Cube.js. I attempted using the asyncModule, but it was not clear how to implement it correctly.

I want to add these three measures by grouping the sk_dim_courses to calculate progress based on the completion of all courses by the user. Subsequently, I aim to count the percentage of users who have completed all courses, the percentage of users who have completed at least one lesson, and the percentage of users who have not started any lessons.

Thank you for your assistance!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.