迁移指南

本指南包含将 Core Reporting API v3 迁移至 Analytics Reporting API v4 的步骤。

简介

为了充分利用 Analytics Reporting API v4 中引入的新功能,请迁移代码以使用这一 API。本指南显示了 Core Reporting API v3 中的请求和 Analytics Reporting API v4 中的请求的对应关系,以简化迁移工作。

Python 迁移

如果您是 Python 开发者,请使用 GitHub 上的 GAV4 助手库,将 Google Analytics(分析)Core Reporting API v3 请求转化为 Analytics Reporting API v4 请求。

端点

Core Reporting API v3 与 Analytics Reporting API v4 的端点和 HTTP 方法有所不同:

v3 端点

GET https://www.googleapis.com/analytics/v3/data/ga

v4 端点

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet

以下示例比较了 v3 中的请求和 v4 中的等效请求:

v3

v3 参考文档

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    &metrics=ga:users&dimensions=ga:pagePath

v4

v4 参考文档

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    "metrics":[
    {
      "expression":"ga:users"
    }],
    "dimensions": [
    {
      "name":"ga:pagePath"
    }]
  }]
}

客户端库和发现服务

如果您使用 Python、JavaScript 或其他建立在 Google Discovery Service 基础上的客户端库,您需要为 Reporting API v4 提供这一发现文档的位置。

Python

from apiclient import discovery

...

# Build the Analytics Reporting API v4 authorized service object.
analyticsReporting = discovery.build(
  'analyticsreporting',
  'v4',
  http=http,
  discoveryServiceUrl='https://analyticsreporting.googleapis.com/$discovery/rest')

JavaScript

gapi.client.load(
  'https://analyticsreporting.googleapis.com/$discovery/rest',
  'v4'
).then(...)

Java 和 PHP 客户端库是预建的,但您可以使用发现服务和 Google API 生成器生成这些库。

请求

API v4 参考详细说明了请求正文的结构。以下部分说明将 v3 请求参数迁移到 v4 请求参数的方法。

数据视图 ID

在 v3 中,用于接受“表格 ID”的 ids 参数格式为 ga:XXXX,其中 XXXX 是数据视图(配置文件)ID。但在 v4 中,数据视图(配置文件)ID 要在请求正文中的 viewId 字段进行指定。

以下示例比较了 v3 请求中的 ids 参数以及 v4 请求中的 viewId 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    ...
  }]
}

日期范围

Analytics Reporting API v4 可让您在一个请求中指定多个日期范围,并通过 dateRanges 字段获取 DateRange 对象的列表。在 v3 中,您可以使用 start-dateend-date 参数在请求中指定一个日期范围。

以下示例比较了 v3 请求中的 start-dateend-date 参数以及 v4 请求中的 dateRanges 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    ...

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    ....
  }]
}

指标

v3 metrics 参数对应于获取 Metric 对象列表的 v4 metrics 字段。

以下示例比较了 v3 请求中的 metrics 参数和 v4 请求中的 metrics 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
    &start-date=2015-11-01&end-date=2015-11-06 \
    &metrics=ga:users,ga:sessions \
    ...

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    "viewId":"XXXX",
    "dateRanges":[
    {
      "startDate":"2015-11-01",
      "endDate":"2015-11-06"
    }],
    "metrics":[
    {
      "expression":"ga:users"
    },{
      "expression":"ga:sessions"
    }],
    ...
  }]
}

维度

v3 dimensions 参数对应于获取 Dimension 对象列表的 v4 dimensions 字段。

以下示例比较了 v3 请求中的 dimensions 参数以及 v4 请求中的 dimensions 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &dimensions=ga:country,ga:browser&... \

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "dimensions": [
    {
      "name":"ga:country"
    },{
      "name":"ga:browser"
    }],
    ...
  }]
}

排序

v3 sort 参数等效于获取 OrderBy 对象列表的 v4 orderBys 字段。

在 v4 中,要按照维度或指标值对结果排序:

  • 通过 fieldName 字段提供其名称或别名。
  • 通过 sortOrder 字段指定排序顺序(ASCENDINGDESCENDING)。

以下示例比较了 v3 请求中的 sort 参数和 v4 请求中的 orderBy 字段;它们均以降序对用户进行排序,按照字母顺序对来源进行排序:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &sort=-ga:users,ga:source

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "orderBys": [
    {
      "fieldName": "ga:users",
      "sortOrder": "DESCENDING"
    },{
      "fieldName": "ga:source"
    }],
  }]
}

抽样级别

v3 samplingLevel 参数对应于 v4 samplingLevel 字段。在 v3 中,接受的 samplingLevel 值是 FASTERHIGHER_PRECISIONDEFAULT;在 v4 中,接受的 samplingLevel 值是 SMALLLARGEDEFAULT。注意 v3 中的 FASTER 在 v4 中已更改为 SMALLHIGHER_PRECISION 更改为 LARGE

以下示例比较了 v3 请求中的 samplingLevel 参数以及 v4 请求中的 samplingLevel 字段:

v3

https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX ...\
samplingLevel=HIGHER_PRECISION

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "samplingLevel": "LARGE"
  }]
}

细分

v3 segment 参数对应于获取 Segment 对象列表的 v4 segments 字段。

细分 ID

在 v4 中,要按照细分 ID 请求细分,请构建一个 Segment 对象,并通过 segmentId 字段提供其 ID。

以下示例比较了 v3 请求中的 segment 参数以及 v4 请求中的 segments 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=gaid::-11

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "viewId": "XXXX",
    "segments": [{
      "segmentId": "gaid::-11"
    }]
  }]
}

动态细分

在 v4 中,为表达更复杂的细分定义,请使用包含 DynamicSegment 对象的 segments 字段。

以下示例比较了 v3 请求中的 segment 参数以及 v4 请求中包含 DynamicSegment 对象的 segments 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "segments": [{
      "dynamicSegment": {
        "name": "segment_name",
        "sessionSegment": {
          "segmentFilters": [{
            "simpleSegment": {
              "orFiltersForSegment": [{
                "segmentFilterClauses": [{
                  "dimensionFilter": {
                    "dimensionName": "ga:medium",
                    "operator": "EXACT",
                    "expressions": [ "referral" ]
                  }
                }]
              }]
            }
          }]
        }
      }
    }]
  }]
}

您可以在细分中结合使用条件和顺序:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=users::condition::ga:revenue>10;sequence::ga:deviceCategory==desktop->>ga:deviceCategory==mobile

v4

  "reportRequests": [{
      "dateRanges": [
            { "endDate": "2014-11-30", "startDate": "2014-11-01" }
      ],
      "metrics": [
          {"expression": "ga:pageviews"},
          {"expression": "ga:sessions"}
      ],
      "viewId": "XXXX",
      "dimensions":[{"name":"ga:medium"}, {"name":"ga:segment"}],
      "segments": [{
        "dynamicSegment": {
        "name": "segment_name",
        "userSegment": {
          "segmentFilters": [{
            "simpleSegment": {
              "orFiltersForSegment": [{
                "segmentFilterClauses": [{
                  "metricFilter": {
                    "metricName": "ga:sessions",
                    "operator": "GREATER_THAN",
                    "comparisonValue": "10"
                  }
                }]
              }]
            }
          },
          {
            "sequenceSegment": {
              "segmentSequenceSteps": [{
                "orFiltersForSegment": [{
                  "segmentFilterClauses": [{
                    "dimensionFilter": {
                      "dimensionName": "ga:deviceCategory",
                      "operator": "EXACT",
                      "expressions": ["desktop"]
                    }
                  }]
                }],
                "matchType": "PRECEDES"
              },{
                "orFiltersForSegment": [{
                  "segmentFilterClauses": [{
                    "dimensionFilter": {
                      "dimensionName": "ga:deviceCategory",
                      "operator": "EXACT",
                      "expressions": ["mobile"]
                    }
                  }]
                }]
              }]
            }
          }]
        }
      }
    }]
  }]

v4 中的 v3 细分语法

v4 API 中的 segmentId 字段支持 v3 API 中的细分语法。

以下示例说明 v4 等效请求中的 segmentId 字段如何支持 v3 请求中的 segment 参数:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
&segment=sessions::condition::ga:medium==referral

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "viewId": "XXXX",
    "segments": [{
      "segmentId": "sessions::condition::ga:medium==referral"
    }]
  }]
}

过滤器

v4 使用 dimensionFilterClauses 过滤维度,使用 metricFilterClauses 过滤指标。dimensionFilterClauses 包含 DimensionFilter 对象列表;metricFilterClauses 包含 MetricFilter 对象列表。

以下示例比较了 v3 请求中的 filters 参数以及 v4 请求中的 dimensionFilterClauses 字段:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga:XXXX \
  &start-date=2015-06-01&end-date=2015-07-31&metrics=ga:users& \
  dimensions=ga:browser&filters=ga:browser==Firefox

v4

  "reportRequests": [{
      "dateRanges": [
            { "endDate": "2014-11-30", "startDate": "2014-11-01" }
      ],
      "metrics": [
          {"expression": "ga:pageviews"},
          {"expression": "ga:sessions"}
      ],
      "viewId": "XXXX",
      "dimensions":[{"name":"ga:browser"}, {"name":"ga:country"}],
      "dimensionFilterClauses": [{
           "filters": [{
                "dimension_name": "ga:browser",
                "operator": "EXACT",
                "expressions": ["Firefox"]
            }]
      }]
  }]

v4 中的 v3 过滤器语法

虽然 v4 中的 filtersExpression 字段支持 v3 中的 filters 语法,还是请使用 dimensionFilterClausesmetricFilterClauses 过滤维度和指标。

以下示例说明 v4 等效请求中的 filtersExpression 字段如何支持 v3 请求中的 filters 参数:

v3

GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga%XXXX \
&filters=ga:browser==Firefox

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [{
    ...
    "filtersExpression": "ga:browser==Firefox"
  }]
}

空行

v3 include-empty-rows 参数对应于 v4 中的 includeEmptyRows 字段。v3 参数默认值为 true,而在 v4 中该字段默认值为 false。如果您没有在 v3 中设置该值,则需要在 v4 中将该值设置为 true

以下示例比较了 v3 请求中的 include-empty-rows 参数以及 v4 请求中的 includeEmptyRows 字段:

v3

https://www.googleapis.com/analytics/v3/data/ga? ...\
    &include-empty-rows=true

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    "includeEmptyRows": "true",
  }]
}

分页

v4 使用 pageTokenpageSize 字段对大量结果进行分页。而 pageToken 取自响应对象的 nextPageToken 属性。

以下示例比较了 v3 请求中的 start-indexmax-results 参数和 v4 请求中的 pageTokenpageSize 字段:

v3

https://www.googleapis.com/analytics/v3/data/ga? ...\
    &start-index=10001&max-results=10000

v4

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests":[
  {
    ...
    # Taken from `nextPageToken` of a previous response.
    "pageToken": "10000",
    "pageSize": "10000",
  }]
}

标准参数

Analytics Reporting API v4 支持 v3 API 中的大部分标准查询参数,但不支持 userIpcallback 参数。

以下示例比较了 v3 请求和 v4 请求中的 quotaUser 参数:

v3 端点

GET https://www.googleapis.com/analytics/v3/data/ga?quotaUser=1X3F2F2

v4 端点

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet?quotaUser=1X3F2F2

响应

由于 v4 允许在一个 HTTP 请求中提交多个 ReportRequest 对象,您可以在响应中获得一组报告对象。对于提交的每个 ReportRequest,您可以在响应中获得相应的报告

报告

v4 报告中有三个顶级字段:columnHeaderdatanextPageToken

由于 v4 响应正文不包含对所有查询参数的响应,这与 v3 响应不同,要获得对特定查询参数的响应,客户端应用必须将该参数添加到 ReportRequest

我们已经在分页一节中说明了 nextPageToken,因此先了解一下 columnHeader 对象。

列标题

列标题包含一列已命名维度和一个 MetricHeader 对象,后者包含一列 MetricHeaderEntry 对象。每个 MetricHeaderEntry 对象指定指标 name 及其 type(币种、百分比等等),用于确定输出结果的格式。

以下示例比较了 v3 响应中的 columnHeaders 字段以及 v4 响应中的 columnHeader 字段:

v3

"columnHeaders": [
    {
        "name":"ga:source",
        "columnType":"DIMENSION",
        "dataType":"STRING"
    },{
        "name":"ga:city",
        "columnType":"DIMENSION",
        "dataType":"STRING"
    },{
        "name":"ga:sessions",
        "columnType":"METRIC",
        "dataType":"INTEGER"
    },{
        "name":"ga:pageviews",
        "columnType":
        "METRIC",
        "dataType":"INTEGER"
    }
]

v4

"columnHeader": {
    "dimensions": [
        "ga:source",
        "ga:city"
    ],
    "metricHeader": {
        "metricHeaderEntries": [
            {
                "name": "ga:pageviews",
                "type": "INTEGER"
            },
            {
                "name": "ga:sessions",
                "type": "INTEGER"
            }
        ]
    }
},

报告行

Core Reporting API v3 在 rows 数组中返回报告数据,其中包括请求的维度和指标。

Analytics Reporting API v4 在 ReportRow 对象中返回报告数据,其中包含一组 dimensions 和一组 DateRangeValues 对象,每个数组包含一个或两个日期范围,如下图所示:

报告行

v3

"rows": [
    [
        "google",
        "Philadelphia",
        "60",
        "5"
    ],
    [
        "google",
        "Johnstown",
        "21",
        "1"
    ],
    [
        "google",
        "Progress",
        "7",
        "1"
    ]
],

v4

"rows": [
    {
        "dimensions": [
            "google",
            "Philadelphia"
        ],
        "metrics": [
            {
                "values": [
                    "60",
                    "5"
                ]
            }
        ]
    },
    {
        "dimensions": [
            "google",
            "Johnstown"
        ],
        "metrics": [
            {
                "values": [
                    "21",
                    "1"
                ]
            }
        ]
    },
    {
        "dimensions": [
            "google",
            "Progress"
        ],
        "metrics": [
            {
                "values": [
                    "7",
                    "1"
                ]
            }
        ]
    }
],

抽样数据

如果对结果进行了抽样,则 Core Reporting API v3 会返回值为 true 的布尔型字段 containsSampledData

但如果是对数据进行了抽样,那么 Analytics Reporting API v4 不会返回布尔值,而是返回 samplesReadCountssamplingSpaceSizes 字段。如果未对结果进行抽样,将不会定义这些字段。以下 Python 示例显示了在报告包含抽样数据的情况下应如何进行计算:

def ContainsSampledData(report):
  """Determines if the report contains sampled data.

   Args:
       report (Report): An Analytics Reporting API v4 response report.

  Returns:
      bool: True if the report contains sampled data.
  """
  report_data = report.get('data', {})
  sample_sizes = report_data.get('samplesReadCounts', [])
  sample_spaces = report_data.get('samplingSpaceSizes', [])
  if sample_sizes and sample_spaces:
    return True
  else:
    return False

下例中的响应所包含的抽样数据来自有两个日期范围的请求。这些结果计算自约 1500 万个会话的抽样空间中的约 50 万个样本

{
  "reports":
  [
    {
      "columnHeader": {
        ...
      },
      "data": {
        ...
        "samplesReadCounts": [ "499630","499630"],
        "samplingSpaceSizes": ["15328013","15328013"],
      }
    }
  ]
}

解析 v4 响应

以下示例代码解析和输出 Analytics Reporting API v4 响应:

Python

def printResponse(self, response):
  """Parses and prints the Analytics Reporting API v4 response"""

  for report in response.get('reports', []):
    columnHeader = report.get('columnHeader', {})
    dimensionHeaders = columnHeader.get('dimensions', [])
    metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
    rows = report.get('data', {}).get('rows', [])

    for row in rows:
      dimensions = row.get('dimensions', [])
      dateRangeValues = row.get('metrics', [])

      for header, dimension in zip(dimensionHeaders, dimensions):
        print header + ': ' + dimension

      for i, values in enumerate(dateRangeValues):
        print 'Date range (' + str(i) + ')'
        for metricHeader, value in zip(metricHeaders, values.get('values')):
          print metricHeader.get('name') + ': ' + value

Java

public static void printResponse(GetReportsResponse response) {

  for (Report report: response.getReports()) {
    ColumnHeader header = report.getColumnHeader();
    List<String> dimensionHeaders = header.getDimensions();
    List<MetricHeaderEntry> metricHeaders = header.getMetricHeader().getMetricHeaderEntries();
    List<ReportRow> rows = report.getData().getRows();

    for (ReportRow row: rows) {
      List<String> dimensions = row.getDimensions();
      List<DateRangeValues> metrics = row.getMetrics();
      for (int i = 0; i < dimensionHeaders.size() && i < dimensions.size(); i++) {
        System.out.println(dimensionHeaders.get(i) + ": " + dimensions.get(i));
      }

      for (int j = 0; j < metrics.size(); j++) {
        System.out.print("Date Range (" + j + "): ");
        DateRangeValues values = metrics.get(j);
        for (int k = 0; k < values.size() && k < metricHeaders.size(); k++) {
          System.out.println(metricHeaders.get(k).getName() + ": " + values.get(k));
        }
      }
    }
  }
}

错误处理

因为 v4 中的错误响应格式与 v3 中的错误响应格式不同,请更新您的代码以处理 v4 错误响应。

以下示例比较 v3 中的错误响应和 v4 中的等效错误响应:

v3

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "insufficientPermissions",
    "message": "User does not have sufficient permissions for this profile.",

   }
  ],
  "code": 403,
  "message": "User does not have sufficient permissions for this profile."
 }
}

v4

{
 "error": {
  "code": 403,
  "message": "User does not have sufficient permissions for this profile.",
  "status": "PERMISSION_DENIED",
  "details": [
   {
    "@type": "type.googleapis.com/google.rpc.DebugInfo",
    "detail": "[ORIGINAL ERROR] generic::permission_denied: User does not have sufficient permissions for this profile. [google.rpc.error_details_ext] { message: \"User does not have sufficient permissions for this profile.\" }"
   }
  ]
 }
}