展平Google Analytics(分析)数据(具有重复的字段)不再起作用

Flattening Google Analytics data (with repeated fields) not working anymore

我们拥有一个高级Google Analytics(分析)帐户,该帐户可让我们访问行级事件数据。 该数据每天导出到Google Bigquery,并且每天都会在数据集中创建一个新表。

直到一周前,我们可以将Google Analytics(分析)数据展平到临时登台表,然后将其导出为CSV,从而将其导出为CSV。 我们过去这样做的查询是这样的:

1
2
3
4
5
SELECT * FROM
    flatten([xxxxxxxx.ga_sessions_20140829],hits),
    flatten([xxxxxxxx.ga_sessions_20140828],hits),
    flatten([xxxxxxxx.ga_sessions_20140827],hits),
    flatten([xxxxxxxx.ga_sessions_20140826],hits)

昨天我注意到此查询现在将引发错误:

1
Cannot output multiple independently repeated fields at the same time. Found customDimensions_value and hits_product_productSKU

显然,关于flatten()函数已经有所更改,因为hits_product_productSKU是hits字段的子代。

我还尝试了查询历史记录中的一些旧查询,但它们也被破坏了。
没有任何发行说明提及任何更改,所以发生了什么事?

如何再次导出Google Analytics BigQuery导出文件中的所有内容?


这实际上是我上周提交的错误修正的结果,可防止您得到错误的结果。

默认情况下,BigQuery会展平所有查询结果,然后再返回它们,但是我们只想展平一个独立重复的字段,以避免数据的跨乘积扩展。错误在于,在某些情况下,我们对多个重复字段的检查未能考虑父记录的重复性,这导致我们无法展平一些独立重复的字段。这意味着我们可以返回扁平行,其中独立的重复值实际上被"拉平"为相关的重复值,而不是生成叉积,这实际上是错误的结果。

您在此处看到的是经过更严格检查的结果:在尝试展平结果之前,您的输出架构中有(至少)两个重复字段。

另一个需要注意的重要事项是FLATTEN([table-value],[field])函数只会使指定为第二个参数的字段的重复性平坦。当您说扁平化([xxxxxxxx.ga_sessions_20140829],hits)时,您仅在扁平化" hits"记录。如果您还想展平其重复的子展位(产品,促销等),则必须为这些字段明确添加另一个展平,例如:

FLATTEN(FLATTEN([xxxxxxxx.ga_sessions_20140829],hits.hits.product)

-

您有两种选择可以使示例工作:

1)选择较少的字段。如果只在乎某些字段的输出变平,可以通过显式选择仅关注的字段,从查询结果中删除独立重复的字段。

2)添加更多FLATTEN。您需要平铺每个重复的字段,该字段至少要包含hits,hits.product和customDimensions。您可能会发现错误消息随后会抱怨不同的重复字段:在架构中的重复字段上添加更多FLATTEN,直到它起作用为止。


如果您使用的是BigQuery Web Console,请选择"目标表",单击"允许大结果",然后取消选中"拼合结果"。

如果您使用的是bq命令行工具:

1
bq query --allow_large_results --noflatten --destination_table NAME_OF_TABLE "SELECT * from FLATTEN( [dataset], hits)"


标准sql

对于那些想将GA数据导入到关系数据库中的人:请注意,嵌套模式实际上是将多个关系表放入一个嵌套结构中-它们是等效的,因此在这里进行平面展平并不是最好的解决方案:您希望将表再次!
这样,您可以节省大量存储空间,并且查询速度可能会更快。

您可以将GA数据视为3个关系表:

  • 会话表
  • 命中表
  • 产品表

要获取会话表,您可以使用类似

1
2
3
4
5
6
7
8
9
10
11
-- session table
SELECT
  * EXCEPT(hits,
    customDimensions),
  CONCAT('{',(
    SELECT
      STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
    FROM
      t.customdimensions),'}') as customDimensions
FROM
  `project.dataset.ga_sessions_20171031` AS t

customDimensions聚合为json字符串。

与点击数表类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- hits table
SELECT
 fullvisitorid,
 visitid,
 visitstarttime,
 h.* EXCEPT(product,
 customdimensions, customMetrics, customVariables, promotion, experiment),
 CONCAT('{',(
   SELECT
     STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
   FROM
     h.customdimensions),'}') AS hitsCustomDimensions,
 CONCAT('{',(
   SELECT STRING_AGG(CONCAT(CAST(index AS string),':',cast(value as string)) )
   FROM h.custommetrics),'}') AS hitsCustomMetrics
FROM
 `project.dataset.ga_sessions_20171031` AS t,
 t.hits AS h

您可以使用子选择添加促销和实验,就像我对customDimensions所做的那样。

使用fullvisitorid + visitstarttime / visitid的链接加入具有匹配的会话(GA会话包括午夜拆分:使用visitStartTime而不是visitid!如果要忽略午夜拆分,请使用visitid-尽管拆分??,该链接保持不变)

对于产品,您需要将匹配编号添加到"会话ID"中以获得唯一标识符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- product table
SELECT
  fullvisitorid,
  visitid,
  visitstarttime,
  h.hitNumber,
  p.* EXCEPT(customdimensions, customMetrics),
  CONCAT('{',(
    SELECT STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
    FROM p.customdimensions),'}') AS productsCustomDimensions,
  CONCAT('{',(
    SELECT STRING_AGG(CONCAT(CAST(index AS string),':',cast(value as string)) )
    FROM p.custommetrics),'}') AS productsCustomMetrics
FROM
  `project.dataset.ga_sessions_20171031` AS t,
  t.hits AS h, h.product as p

现在,您具有3个关系/"平面"表,可以根据需要在任何关系数据库中进行联接。


在连接之前,您必须使用扁平化查询。只需选择错误中提到的字段并使用嵌套展平:

1
2
3
4
SELECT * FROM
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140829],hits),customDimensions_value),hits_product_productSKU),
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140828],hits),customDimensions_value),hits_product_productSKU),
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140827],hits),customDimensions_value),hits_product_productSKU),    flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140826],hits),customDimensions_value),hits_product_productSKU)

我怀疑Google Analytics Premium生成的表已经增加了新列。除非您的查询使用*选择器,并且新列之一恰好包含嵌套值,否则添加列应该不是问题。

推荐的解决方案:代替使用*,显式询问您需要的列。