Core Reporting API - How to use multiple dimensionFilterClauses filters?

Gianluca picture Gianluca · Aug 2, 2016 · Viewed 8.4k times · Source

I'm trying to use multiple dimensionFilterClauses into a Core Reporting API V4 query. If I use just a filter on the ga:adwordsCustomerID dimension everything goes fine, but when I add a second filter on the ga:adTargetingType dimension it throws a "Status 400: Bad request" error.

This is the query I wrote:

    return analytics.reports().batchGet(
        body={"reportRequests": [{
            "pageSize": 10000,
            "viewId": VIEW_ID,
            "dateRanges": [
                {"startDate": "31daysAgo", "endDate": "yesterday"}
            ],
            "dimensions": [
                {"name": "ga:adwordsCampaignID"},
                {"name": "ga:adwordsAdGroupID"},
                {"name": "ga:adwordsCriteriaID"}
            ],
            "metrics": [
                {"expression": "ga:adClicks"},
                {"expression": "ga:adCost"},
                {"expression": "ga:uniquePurchases"},
                {"expression": "ga:itemRevenue"},
                {"expression": "ga:CPC"},
                {"expression": "ga:ROAS"}
            ],
            "dimensionFilterClauses": [
                {"filters": [
                    {"dimensionName": "ga:adwordsCustomerID",
                     "operator": "EXACT",
                     "expressions": ["2096809090"]},
                    {"dimensionName": "ga:adTargetingType",
                     "operator": "EXACT",
                     "expressions": ["Keyword"]}
                ]}
            ],
            "metricFilterClauses": [
                {"filters": [
                    {"metricName": "ga:adCost",
                     "operator": "GREATER_THAN",
                     "comparisonValue": "0"}
                ]}
            ],
            "orderBys": [
                {"fieldName": "ga:adClicks",
                 "sortOrder": "DESCENDING"}
            ]}
        ]}
    ).execute()

Do you know what's wrong with the above query body?

Answer

Matt picture Matt · Aug 4, 2016

Analytics Reporting API V4 Filtering

The ReportRequest takes an array of DimensionFilterClauses. These clauses are combined with the logical AND operator. Ie. If you had two DimensionFilterClause objects: A and B; the API will only return values that meet both conditions in A AND B.

Each DimensionFilterClause takes an array of DimensionFilters (called filters). These filters are combined with the logical OR operator. Ie. if you had two DimensionFilter objects C and D within a DimensionFilterClause; the API would return results that satisfied either C or D.

Example

Below is an example request with two DimensionFilterClauses; ga:adWordsCampaignID==8675309 AND ga:adwordsAdGroupID==12345 API Explorer example:

{
  "reportRequests": 
  [
    {
      "viewId": "XXXX",
      "dimensions": 
      [
        {"name": "ga:adwordsCampaignID"},
        {"name": "ga:adwordsAdGroupID"},
        {"name": "ga:adwordsCriteriaID"}
      ],
      "metrics": 
      [
        {"expression": "ga:adClicks"},
        {"expression": "ga:adCost"}
      ],
      "metricFilterClauses": 
      [
        {
          "filters": 
          [
            {
              "metricName": "ga:adCost",
              "operator": "GREATER_THAN",
              "comparisonValue": "0"
            }
          ]
        }
      ],
      "dimensionFilterClauses": 
      [
        {
          "filters": 
          [
            {
              "dimensionName": "ga:adwordsCampaignID",
              "operator": "EXACT",
              "expressions": ["8675309"]
            }
          ]
        },
        {
          "filters": 
          [
            {
              "dimensionName": "ga:adwordsAdGroupID",
              "operator": "EXACT",
              "expressions": 
              ["12345"],
            }
          ]
        }
      ]
    }
  ]
}

Conclusion

From the outset it does not appear that there is anything wrong with your API request body, if there was you would get an error message. But its more likely that you didn't intend to request for:

        "dimensionFilterClauses": [
            {"filters": [
                {"dimensionName": "ga:adwordsCustomerID",
                 "operator": "EXACT",
                 "expressions": ["2096809090"]},
                {"dimensionName": "ga:adTargetingType",
                 "operator": "EXACT",
                 "expressions": ["Keyword"]}
            ]}
        ],

But you intended to request for:

        "dimensionFilterClauses": [
            {"filters": [
                {"dimensionName": "ga:adwordsCustomerID",
                 "operator": "EXACT",
                 "expressions": ["2096809090"]},
            ]},{"filters": [
                {"dimensionName": "ga:adTargetingType",
                 "operator": "EXACT",
                 "expressions": ["Keyword"]}
            ]}
        ],

My recommendation when no data shows up is to first remove the filter, and then verify you have the exact string you are searching for. Also if you do not have the full string you can use a different filter.operator such as PARTIAL or BEGINS_WITH.

Error handling

It is also smart to use proper error handling especially when debugging:

try:
  response = analyticsreporting.reports().batchGet(
    body=requestBody
  ).execute()

except TypeError, error:
  # Handle errors in constructing a query.
  print 'There was an error in constructing your query : %s' % error

except HttpError, error:
  # Handle API errors.
  print ('There was an API error : %s : %s' %
         (error.resp.status, error.resp.reason))

Updated: ga:adTargetingType==Keyword Example

From the comment below it was requested to give an example of dimension filter with ga:adTargetingType==Keyword. Use the API Example here to prove to yourself that it works (just change VIEW_ID to your view view id and hit "Authorize and Execute"). JSON body below:

{
  "reportRequests": 
  [
    {
      "viewId": "VIEW_ID",
      "metrics": [{"expression": "ga:sessions"}],
      "dimensions": [{"name": "ga:adTargetingType"}],
      "dimensionFilterClauses": 
      [
        {
          "filters": 
          [
            {
              "dimensionName": "ga:adTargetingType",
              "operator": "EXACT",
              "expressions": ["Keyword"]
            }
          ]
        }
      ]
    }
  ]
}

I always like to start small and work up. By removing the other parameters and fields I can prove to myself what is working and what is not. This example is the bare minimum required request that filters for ga:keyword==Keyword.

Second Update:

The actual error message you are getting is as follows:

"Selected dimensions and metrics cannot be queried together."

The dimension ga:adTargetingType cannot be queried with the following metrics:

  • ga:impressions
  • ga:adClicks
  • ga:adCost
  • ga:CPM
  • ga:CPC
  • ga:CTR
  • ga:costPerTransaction
  • ga:costPerGoalConversion
  • ga:costPerConversion
  • ga:RPC
  • ga:ROAS