Server side extensions
Qlik's Server Side Extension feature enables you to extend the engine with custom calculations.
There are two ways you can do this; by defining custom functions, and by enabling runtime script evaluation.
Functions
Functions are defined based on the input type you expect them to have and could be one of scalar, aggregation or tensor.
To explain them, we're going to assume we have the following data model:
| Product group | Product | Sales |
|---|---|---|
| Snack | Chips | 19 |
| Snack | Popcorn | 11 |
| Snack | Cookies | 18 |
| Dairy | Cheese | 12 |
1 2 3 4 5 6 7 8 | |
Data in SSE is received in the shape of bundles:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Tensor (and Scalar)
Tensor is used when there is a one-to-one relationship between the fields in the cube and the expressions you provide to the SSE function.
If we use Product group as dimension and pass in sum(Sales) as a parameter to the function, we would receive one bundle with one row per Product group:
[48, 12]
Example
The following example returns the value 'green' if the value of the expression sum(Sales) is > 20, otherwise it returns 'red'.
The expression:
1 | |
The SSE function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
Aggregation
Aggregation is used when there is a one-to-many relationship between the fields in the cube and the expressions you provide to the SSE function. Common use cases are calculating sum, avg, concatenation etc.
If we use Product group as dimension and pass in Sales as a parameter to the function, we would receive three bundles:
- For Product group
'Snacks':[19, 11, 18] - For Product group
'Dairy':[12] - For total:
[19, 11, 18, 12]
Example
If we want to calculate the sum of Sales for each Product group, we simply aggregate the rows in each bundle:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Script evaluation
Danger
Enabling script evaluation is dangerous! For more information why please check eval() function description
Script evaluation makes it easy to run some basic arithmetic and string manipulation.
To simplify the access to values inside scripts:
- bundles are first remapped into an
argsparameter. The values insideargsare:- strings when parameter type is STRING
- numbers when parameter type is NUMERIC
- dual when parameter type is DUAL
-
the script is evaluated by wrapping it inside a function:
1 2 3
function(args, params, common) { // script evaluated here }argsmay be one of(string | number | dual)[][]- when any of the*Aggrfunctions are called(string | number | dual)[]params<Parameter[]>common<CommonRequestHeader>- values are then remapped back to appropriate bundles
Example
Calculate the sum of Sales per Product Group:
1 | |
In this example we're using one of the *Aggr functions, the value of args will then be:
- For Product group
'Snacks':[[19], [11], [18]] - For Product group
'Dairy':[[12]] - For total:
[[19], [11], [18], [12]
Example
Return 'green' if the value of the expression sum(Sales) is > 20, otherwise return 'red'.
1 | |
args will in this case be:
- For Product group
'Snacks':[48] - For Product group
'Dairy':[12]
In this example, we use *Ex because we want to get the numeric value of sum(Sales) by specifying N as the first parameter. The values inside args will therefore be the numData part of the dual. We use *Str because we want a string as output.
Table load
It's possible to load entire tables and augment script data through a table load defined in the script.
Example
Let's first define a function that has a table description and returns additional columns of data:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
In the load script we can then load that additional data using the Load ... Extension syntax:
1 2 3 4 5 6 7 8 9 10 | |
which will result in the following table being added to the data model:
| Product | fat | protein | carbs |
|---|---|---|---|
| Chips | 20 | 25 | 4 |
| Popcorn | 12 | 4 | 78 |
| Cookies | 7 | 35 | 53 |
| Cheese | 6 | 24 | 65 |