AML Extend
Introduction
AML Extend is a function that is applied to an analytics object to produce a new object that takes on the original properties.
Consider the following example where a User model is extended for two use cases with different requirements:
Model users {
// Details of these dimensions are omitted for brevity
dimension id {}
dimension email {}
dimension signed_up_at {}
dimension first_logged_in {}
}
// Extend Users model and add a new dimension `activated_at`
Model activatedUsers = users.extend({
// Details of this dimension are omitted for brevity
dimension activated_at {},
})
// Extend Users model and hide the dimension `email` from end users
Model anonymizedUsers = users.extend({
dimension email { hidden: true }
})
Without AML Extend, you would have to duplicate the model code multiple times, which is error-prone and requires careful maintenance.
How AML Extend works
AML Extend has the following properties:
- Inheritance. When you edit properties in the base objects, and these changes will be propagated to all extending objects.
- Additive. You can add new properties to the extending objects that do not exist in the base objects.
- Overriding. You can modify properties that the extending objects inherit from the base objects, without modifying the original properties.
AML extend will follow these steps when being used:
- Clone the object that is being extended.
- Create a new extending object from the extending code.
- Merge and resolve any conflicts between these two objects. If a field is defined in both objects, AML always uses the version in the extending object (overriding).
Example:
Model users {
label: 'Users'
dimension id { ... }
}
Model activatedUsers = users.extend({
label: 'Activated users'
dimension activated_at { ... }
})
// Steps:
// 1. Clone the "users" object into a new copy (users_cloned)
// 2. Create a new extending object from the extending code block
// {
// label: 'Activated users'
// dimension activated_at { ... }
// }
// 3. Merge users_cloned to the newly extending object.
// The 'label' field will be overridden by the new value.
// Final result:
Model {
label: 'Activated users'
dimension id { ... }
dimension activated_at { ... }
}
Reuse extended logic with AML Partials
When you want to reuse the extended logic, you can use AML Partial, which represents a partial AML object. For example, you can create a PartialDataset
that contains a bunch of metrics, then reuse them in other datasets, like below:
// Define a Partial Type of Dataset which contains a group of metrics
PartialDataset revenue_metrics {
metric gmv { ... }
metric mrr { ... }
metric arr { ... }
}
// In company.dataset.aml
Dataset company_with_revenue = company.extend(revenue_metrics)
// In store.dataset.aml
Dataset store_with_revenue = store.extend(revenue_metrics)
AML Partials ensure that the extended object structure matches the type of the target object, thus improving correctness.
Many Holistics' built-in types support AML Partial: PartialModel
, PartialTableModel
, PartialQueryModel
, PartialDataset
, PartialDashboard
, PartialVizBlock
, PartialPageTheme
and PartialBlockTheme
.
Override nested properties
You can extend an object and add or modify only the properties that you're interested in, without having to re-declare other required properties.
Let's say that you have a data model for employees that contains sensitive salary information. Certain HR team members request data about current employees, including joining dates, to celebrate their anniversaries. But they don't need the salary dimension and are not authorized to access such information. You can extend the original model and hide away the salary dimension by overriding the hidden
attribute only.
// This model contains sensitive employee salary information
Model employeeInfo {
dimension salary {
label: 'Salary'
type: 'number'
hidden: false
definition: @sql {{ #SOURCE.salary }} ;;
}
dimension joining_date {
label: 'Joining Date'
type: 'date'
hidden: false
definition: @sql {{ #SOURCE.joining_date }} ;;
}
}
// This model is exposed to HR team members that need just enough info
// to celebrate employee anniversaries
Model employeeInfoWithoutSalary = employeeInfo.extend({
dimension salary {
// override hidden property without having to re-declare other properties
hidden: true
}
});
Extend cannot be used to completely remove properties from objects. The above example only hides the dimension away by modifying its existing hidden property.
Use cases for AML Extend
As your Holistics project grows in size and complexity, you’ll likely encounter similar situations where it’s useful to define and extend new analytics logic based on existing ones without duplication.
Some use cases for AML Extend: