Virtual Members (KPI Admin)


Overview

Virtual Members provide a powerful way to build advanced queries, measures, and KPIs. It allows you to produce dynamic members for a dimension based on a scripting language. It also would allow you to automatically generate matching KPIs for the conditions set for the Virtual Members.

This page aims to provide you with easy-to-follow steps when working with Virtual members based on common use cases outlined in this page. For any other use cases pertinent to Virtual Members, please reach out to the eMite Consulting Team or your eMite account executive for further guidance.


Scripting Guidelines

General rules to follow when creating Virtual Members:

  • When creating the expression, you must type everything into a single line. Do not use Enter to create a new line.

  • Field names must start with "@".

  • There are some special characters in field names which must be replaced by keywords:

    • The space character (" ") must be replaced by the "_SPACE_" keyword. For example, a field called DATE OPEN is written as @DATE_SPACE_OPEN.

    • The dash character ("-") must be replaced by the "_DASH_" keyword. For example, a field called RefQuery-Price is written as @RefQuery_DASH_Price.

    • The dot character (".") must be replaced by the "_DOT_" keyword. For example, a field "Value.Keyword" is written as @Value_DOT_Keyword.

  • Mind the parenthesis while creating complex expressions.

  • There must be a space before and after the operator. For example, "if(@name1>0)" is an invalid expression. The format should be "if(@name1 > 0)".

 

You may also check out Elastic’s Painless Scripting Guide here.


Creating a Virtual Member

  1. Go to KPI Admin screen to access the Virtual Members configuration page. All Virtual Members previously saved will display on the screen.

  2. Click the Add new record button.
    To edit an existing Virtual Member, click on its edit button.

The Virtual Member Details will display.

 

Virtual Members Details Pop-up

The following screenshot is an example of a fully defined Virtual Member.

Field Name

Description

Field Name

Description

Name

What the Virtual Member will be called. Keep this name in mind when linking it with a dimension.

Description

Brief description of the Virtual Member

Connection, Cube, Dimension

Used to select the dimension that you want to link the Virtual Member with

Condition

Contains the logical conditions for each Virtual Member. In the example above, there are 3 conditions defined:

  • Member #1: Will match all rows of the index where the field “TOTAL_TRANSFERS” is less or equal zero.

  • Member #2: Will match all rows where “TOTAL_TRANSFERS” is between 1 and 30.

  • Member #3: Will match all rows where “TOTAL_TRANSFERS” is between 31 and 60. 

Return

Contains the Member Value that will be returned if the condition is met. In the example above, if we were to select all the members of this Virtual member (DimSample3) in a cube report, the result would be:

Note that the members “Option 0”, “Option B”, and “Option C” are wrapped in a tag called “#MemberValue<value>#”. It will only work if you are using this notation and the page will give you an error if you do not do this.

Member Label

Contains the Member Label that will be visible on the eMite dashboards. Note: The Member Label can be different from the Member Value (see Example 1 below).

There are also Edit and Delete buttons next to each Virtual Member condition and buttons to test your Virtual Member conditions depending on the type of aggregation (COUNT, AVG, SUM, MAX, MIN). Please also make sure to click Save to save the Virtual Member.


Common Use Cases

Grouping Queues

In this example, we will look at how Virtual Members can be used to group queues based on characters within the queue names.

1. Fill out the Name field with what you want the new Virtual Member to be displayed as. 

The name you give the virtual member will also be displayed as the dimension when creating your cube report later. Please keep your users in mind. 

2. Select the appropriate index within which this should appear with the Cubes drop down. In this example, QueueHistory index is selected. 

3. Since we want this to be a new Dimension, leave the Dimensions box blank and tick Create a new dimension

For the purpose of this example, we are using the following expression:

if(@QueueName != null && doc['QueueName'].value.startsWith('SC'))

This will check that the value of the QueueName field is not null, and check for any which start with the letters “SC”, as shown in the image below: 

4. Click Save. Once saved, this will create the new Virtual Member and also create the new Dimension.

5. Click the Count button to check the returned values. This will give you an indication of the number of times this string has been encountered. 

You can replace “SC” with the first few characters of your own naming conventions to suit your unique needs. 

Now you can create a standard cube report using this new dimension as shown below:

You can verify the data by linking the cube to the drillthrough datablock as shown below:

 

To group queue names which include specific characters:

This can be achieved by following the above steps and substituting the condition with the following: 

if(@QueueName != null && doc['QueueName'].value.contains('EMEA'))

We have replaced value.StartsWith, with value.contains

In this example, we used the expression to ensure that the field is not null and to find all field content that contain the text “EMEA”. This text will be specific to your requirements.  

The value member will look like this: 

There are some syntax differences between a text type field and a keyword type field for Virtual Member.

For a text field using comma analyser in Elasticsearch, ie QueueName

  1. Elasticsearch will store the field as array and sort the array items in alphabetical order.

  2. doc['QueueName'].value will return the first item in the array. 

  3. doc['QueueName'].values will return the whole array.

  4. To do exact match with the array items, use doc['QueueName'].values.contains('searchterm') only when one of the array item equal to searchterm will match it.

  5. To do wildcard match with the array items, first convert the array to string. Use doc['QueueName'].values.toString().contains('searchterm'). All the array items that contain searchterm will match it.


Reporting on Null Values

A common requirement is to select the data that is not there. Here is a brief example:

Using the logic above, we will be able to filter all rows where the “Organization” field contains a null value:


Aliasing DNIS/ANI

In this example, we will look at how Virtual Members can be used to alias DNIS/ANI based on characters within the DNIS/ANI.

 

Example 1

if(@Dnis != null && doc['Dnis'].value.contains('DNISorANI'))

else if((@Dnis != null && (doc['Dnis'].value.contains('DNISorANI') || doc['Dnis'].value.contains('DNISorANI') || doc['Dnis'].value.contains('DNISorANI') || doc['Dnis'].value.contains('DNISorANI'))))

else if(@Dnis != null && doc['Dnis'].value.contains('DNISorANI'))

 

Example 2

1. Fill out the Name field with what you want the new Virtual Member to be displayed as. 

2. Select the appropriate index within which this should appear with the Cubes drop down. In this example, QueueHistory index is selected. 

3. Since we want this to be a new dimension, leave the Dimensions box blank and tick Create a new dimension

For the purpose of this example, we are using the following expression:

if(@DNIS != null && doc['DNIS'].value.startsWith('DNIS number'))

This will check that the value of the QueueName field is not null, and check for any which start with the letters “SC”, as shown in the image below: 

4. Click Save. Once saved, this will create the new Virtual Member and also create the new Dimension.

5. Click the Count button to check the returned values. This will give you an indication of the number of times this string has been encountered. 

You can replace “SC” with the first few characters of your own naming conventions to suit your unique needs. 

Now you can create standard cube report using this new dimension as shown below:

You can verify the data by linking the cube to the drillthrough datablock as shown below:

 

To group queue names which include specific characters:

This can be achieved by following the above steps and substituting the condition with the following: 

We have replaced value.StartsWith, with value.contains

In this example, we used the expression to ensure that the field is not null and to find all field content that contain the text “EMEA”. This text will be specific to your requirements.

The value member will look like this: 

There are some syntax differences between a text type field and a keyword type field for Virtual Member.

For a text field using comma analyzer in Elasticsearch, ie QueueName

  1. Elasticsearch will store the field as array, and sort the array items in alphabetical order.

  2. doc['QueueName'].value will return the first item in the array. 

  3.  doc['QueueName'].values will return the whole array.

  4. To do exact match with the array items, use doc['QueueName'].values.contains('searchterm') only when one of the array item equal to searchterm will match it.

  5. To do wildcard match with the array items, first convert the array to string. Use doc['QueueName'].values.toString().contains('searchterm'). All the array items that contain searchterm will match it.


Testing Virtual Members

When adding a new Virtual Member Definition, there are buttons on the bottom of the Virtual Members Details page.

Once you're done creating a new Virtual Member definition, you can test if the aggregation will work on an actual dashboard.

In this very example, the axis generated will be exclusively numeric (items in yellow in the last picture). That means that you can test all basic measures.
In contrast, if one or more axis (return column) have text in it, you can only use the count measure.

If the test is successful, a dialog box similar to the below is shown:

Otherwise, a popup with an error will be displayed.


Additional Reference Information

Virtual Members definitions are built on a language called Painless which is a built-in scripting language of Elasticsearch.

Most of the time, you'll be dealing with string comparisons to evaluate a condition, i.e. If (XXX is true), then it returns something 'YYY'.

XXX and YYY are usually string/text, so you can use the below references for any type of functions around string and text manipulation:

You may also check more Elastic’s Painless Scripting Guide here.