GoodData.CN: Metrics Management 101


  • Anonymous
  • 0 replies

Hello and welcome to Metrics Management 101 on the GoodData.CN Platform where we will describe considerations and best practices for building metrics! In this article, we will dive into metric attributes and core functions to build out your metric catalog for analysis.

 

In GoodData.CN metrics are managed via APIs. A definition of a metric looks like: 

"data": {

"id": "revenue_lost",

"type": "metric",

"attributes": {

"title": "Revenue Lost",

"description": "",

"content": {

"format": "$#,##0",

"maql": "SELECT {metric/order_amount} WHERE {label/order_lines.order_status} in (\"Canceled\",\"Returned\")"

}

}

}

 

Let’s first start with the different metric parameters you will need to create a metric via API:

  1. Metric ID: All measures need a unique identifier (this ID is not visible in the UI). In GoodData.CN, this ID can be any value, but we recommend making this value as semantically identifiable as possible for easy recognition. This will also help in the long run when referenced from other metrics. For example, if you are creating a new metric called “Profit Margin” your ID could be “profit_margin”. 

  2. Metric Title: Name your measure in a universal manner so all of your customers can understand the metric in the same way. Similar to the Metric ID, this name should be semantically recognizable and meaningful. This title will be visible in the UI and will appear in the data catalog in Analytical Designer.

    1. If the measure you are trying to describe is specific to an attribute value try adding it to the name like “Profit Margin (Home Goods)” rather than “Profit Margin”. Another example, “Profit Margin by Week” instead of “Profit Margin”

    2. TIP: If you are aggregating a fact in several different ways for your base metrics (a.k.a. metrics you will use as building blocks for other metrics), try naming them with the Fact first and then the aggregation in brackets. For example, say you want two metrics for fact Amount. You can name them “Amount [Sum]” and “Amount [Avg]”. All metrics in the data catalog in Analytical Designer display these measures in alphabetical order. 

    3. Need help with naming your metric? Check out our Community Article on Metric Naming Best Practices: https://community.gooddata.com/metrics-and-maql-kb-articles-43/best-practices-naming-conventions-for-maql-measures-140 

  3. Metric Definition: This is an optional field that can be added to describe the measure in more detail. The definitions are available in Analytical Designer when the user hovers over the measure in the business catalog.

  4. Metric Format: You can specify how the metric values should be formatted in your insights. Here is a link for the available formatting options.

    1. For example, if you would like to add a dollar sign your metric values you can set your format as “$#,##0.00”. The same can be applied for setting decimals and rounding to the nearest thousands.  

    2. TIP: Alternatively, metric formats can be overwritten in the insight directly, so no need to duplicate your metrics for different formats.

  5. Metric MAQL: In this metric attribute, you will define the MAQL definition for your metric. MAQL (Multi-dimensional Analytical Query Language) is very similar in syntax to SQL but does not include any table joins as the logical data model does the joins for you. MAQL statements always start with ‘SELECT’ and include an aggregation of a fact. All references to pieces of the logical data model (like attributes, facts, and existing measures) are all identified by {type/name}. 

    1. For example, the MAQL statement for Revenue by Category could look like this:

      SELECT {metric/revenue} BY {attribute/products.category} 

       

    2. Alternatively, if you are writing a MAQL definition to filter an attribute, use the label type identifier like this example for Profit Margin (Home Goods):

      SELECT {metric/profit-margin} BY {label/products.category} = "Home"

       

    3. TIP: Because all metric parameters are enclosed in double quotes, don’t forget to escape your quotes with ‘\’. Here’s an example:

      "SELECT {metric/profit-margin} BY {label/products.category} = \"Home\""

       

 

Now that we understand the different metric parameters, let’s take a look at some best practices for building out your metric catalog:

  1. Build out your base metrics first. A base metric is a metric that will be referenced by other metrics. These usually include a basic aggregation of a fact like SUM({fact/order.amount}) or COUNT({attribute/customers.customer_id},{attribute/order.orderid}) Building out these base metrics first will allow you to reference them for later metrics. 

  2. As a rule of thumb, try not to repeat MAQL across metrics - repeat as much as possible in the form of referenced metrics. More references means easier control over changes to existing metrics. You can make your change in one place, rather than across multiple metrics for the same logical change. For example, say you have a metric called # Active Users This Month, that references a metric # Active Users, that references a metric # Users. If the definition for # Users were to change, you could make the update directly in this measure rather than all three metrics.

 

If you are interested in GoodData.CN, please contact us.

Alternatively, test a trial version of GoodData Cloud:

Start Your GoodData Analytics Trial — Commitment-Free


13 replies

How looks full POST request for adding this metric?
"data": { "id": "revenue_lost", "type": "metric", "attributes": { "title": "Revenue Lost", "description": "", "content": { "format": "$#,##0", "maql": "SELECT {metric/order_amount} WHERE {label/order_lines.order_status} in (\"Canceled\",\"Returned\")" } } }

Hi @Vasiliy Ostrovsky ,

 

The full POST request to add the metric via command line will look like the following:

curl http://localhost:3000/api/entities/workspaces/${WORKSPACE_ID}/metrics \
  -H "Content-Type: application/vnd.gooddata.api+json" \
  -H "Accept: application/vnd.gooddata.api+json" \
  -H "Authorization: Bearer ${BEARER_TOKEN}" \
  -X POST \
  -d '{
  "data": {
    "id": "revenue_lost",
    "type": "metric",
    "attributes": {
      "title": "Revenue Lost",
      "description": "",
      "content": {
        "format": "$#,##0",
        "maql": "SELECT {metric/order_amount} WHERE {label/order_lines.order_status} in (\"Canceled\",\"Returned\")"
      }
    }
  }

}'

 

In the example listed above, there are two parameters that will need to be replaced: WORKSPACE_ID and BEARER_TOKEN. The WORKSPACE_ID identifies which workspace you would like to post the metric and the BEARER_TOKEN is used to authenticate the request.

 

The full API documentation is found here: https://www.gooddata.com/developers/cloud-native/doc/1.2/api/api_reference_all/#/entities/createEntity%40Metrics 

 

How to get Bearer Token: https://www.gooddata.com/developers/cloud-native/doc/1.2/administration/auth/user-token/

 

Hope this helps!

Sheila

Thank you, Sheila! And do I need to know measures IDs in order to perform simple calculation?
In fact I need to show value of M1/(M1+M2) as a headline (not within a table). Should I use the  API request or is there a more simple way?

 

 

 

Why do I receive empty data sending this request?

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" https://gooddata-dev.criterionhcm.com/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics \
 

Hi @Vasiliy Ostrovsky,

 

For headline insights, the selected measure must be defined in the measures list. To accomplish this, your suggested method of creating a new measure via API will work!

 

As for the curl command, could you try something like this instead: 

curl https://gooddata-dev.criterionhcm.com/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" -H "Content-Type: application/vnd.gooddata.api+json" \ -H "Accept: application/vnd.gooddata.api+json" \  -X POST \  -d '{ "data": { "id": "metric_test", "type": "metric", "attributes": { "title": "Metric Test", "description": "", "content": { "format": "#,##0", "maql": "SELECT SUM({fact/order_lines.quantity}" } } }}'

I believe your posted command is missing some required entities like the request body. 

 

Hope this helps!
Sheila

Hi @Vasiliy Ostrovsky,

 

For headline insights, the selected measure must be defined in the measures list. To accomplish this, your suggested method of creating a new measure via API will work!

 

As for the curl command, could you try something like this instead: 

curl https://gooddata-dev.criterionhcm.com/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" -H "Content-Type: application/vnd.gooddata.api+json" \ -H "Accept: application/vnd.gooddata.api+json" \  -X POST \  -d '{ "data": { "id": "metric_test", "type": "metric", "attributes": { "title": "Metric Test", "description": "", "content": { "format": "#,##0", "maql": "SELECT SUM({fact/order_lines.quantity}" } } }}'

I believe your posted command is missing some required entities like the request body. 

 

Hope this helps!
Sheila

 

I got this by running your command

 

Hi @Vasiliy Ostrovsky ,

 

Looks like my newlines didn’t copy over in my second message, but the format from the first message still holds true. Here is a command I used in my GoodData.CN Community Edition environment:

 

curl http://localhost:3000/api/entities/workspaces/6c1c6be829584ca39137042a31163501/metrics \
  -H "Content-Type: application/vnd.gooddata.api+json" \
  -H "Accept: application/vnd.gooddata.api+json" \
  -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -X POST \
  -d '{
  "data": {
    "id": "sj_test",
    "type": "metric",
    "attributes": {
      "title": "Test",
      "description": "",
      "content": {
        "format": "#,##0",
        "maql": "SELECT SUM({fact/order_lines.quantity})"
      }
    }
  }
}'

 

I also checked your host (gooddata-dev.criterionhcm.com) and was unable to verify via ping. Could you validate the host where your workspace (daceb3e88abd4bd5a7af036e9876a837) exists in is valid?

 

Hope this helps!
Sheila

What should be the proper MAQL query for the statement including metrics named ‘is_on_cycle’, ‘is_off_cycle’ : SUM(is_off_cycle)/(SUM(is_off_cycle) + SUM(is_on_cycle))?

Hi @Vasiliy Ostrovsky,

 

With existing metrics is_on_cycle and is_off_cycle, your MAQL definition could look like the following:

SELECT {metric/is_off_cycle} / ({metric/is_off_cycle}+{metric/is_on_cycle})

 

Hope this helps!

Sheila

I’m still  getting emply metrics list by running command

C:\Users\vostrovsky>curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" -X GET https://gooddata-dev.criterionhcm.com/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics
{"data":[],"links":{"self":"http://localhost:3000/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics?page=0&size=20","next":"http://localhost:3000/api/entities/workspaces/daceb3e88abd4bd5a7af036e9876a837/metrics?page=1&size=20"}}

Hi @Vasiliy Ostrovsky,

 

If your metric creation APIs ran successfully, the following command can be used to retrieve the created metrics. In my environment, this execution ran successfully:

curl http://localhost:3000/api/entities/workspaces/6c1c6be829584ca39137042a31163501/metrics \
-H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
-X GET

If this still doesn’t work for you or you have other questions you would like to ask, please join our GoodData Community Slack Channel here: https://www.gooddata.com/slack/ I recommend joining the #gd-questions slack channel to post your questions.

 

Hope this helps!
Sheila

 

Hi! I’m trying to calculate ratio of sums via API. I have two Sum metrics without names or aliases. Is it possible to assign name to metrics?

Then I send this POST request with MAQL: script "SELECT {metric/Sum of Hire amount} / ({metric/Sum of Term amount})"

 And get the response:
 

"detail": "Some of given referenced 'metrics' entities do not exist.Not existing IDs: StockId(apiId=Sum of Hire amount, scope=WorkspaceObjectScope(organization=default, space=daceb3e88abd4bd5a7af036e9876a837)), StockId(apiId=Sum of Term amount, scope=WorkspaceObjectScope(organization=default, space=daceb3e88abd4bd5a7af036e9876a837))",

    "status": 400,

    "title": "Bad Request",

    "traceId": "750ad93f87abe878"

Please, help me to get the desired result.

Userlevel 3

Hi!

I just wanted to share updated documentation links with you.
 

API documentation:
 https://www.gooddata.com/developers/cloud-native/doc/latest/api/api_reference_all/#/entities/createEntity%40Metrics 

How to get Bearer Token:
 https://www.gooddata.com/developers/cloud-native/doc/latest/administration/auth/user-token/

 

Reply