使用 BigQuery 提取命中级别数据时,Google Analytics 指标被夸大了

Posted

技术标签:

【中文标题】使用 BigQuery 提取命中级别数据时,Google Analytics 指标被夸大了【英文标题】:Google Analytics Metrics are inflated when extracting hit level data using BigQuery 【发布时间】:2017-05-09 22:18:11 【问题描述】:

我正在尝试在我已链接到 bigquery 的 Google Analytics(分析)汇总属性中显示源属性名称。问题是,当我尝试下面的一些指标时,会变得非常膨胀。我猜这与重复字段有关,但不确定该怎么做。我尝试了许多解决方法,例如使用“max”,但这并没有显示每个属性名称。

除了用户和访问之外的所有指标似乎都被夸大了。

SELECT
  date,
  MAX(CASE
      WHEN EXISTS(  SELECT 1  FROM UNNEST(hits) hits  WHERE REGEXP_CONTAINS(hits.sourcePropertyInfo.sourcePropertyTrackingId, r'82272640')) THEN 'MUG'
      WHEN EXISTS (
    SELECT
      1
    FROM
      UNNEST(hits) hits
    WHERE
      hits.sourcePropertyInfo.sourcePropertyTrackingId = 'Social') THEN 'Social'ELSE 'Website' END) AS Property,
  geoNetwork.country AS Country,
 COUNT(DISTINCT CONCAT(cast(visitId AS STRING),fullVisitorId)) as visits,
 sum(totals.visits) as visits2,
  COUNT(DISTINCT(fullVisitorId)) AS Users,
 h.sourcePropertyInfo.sourcePropertyDisplayName as display,
  SUM((
    SELECT
      SUM(latencyTracking.pageLoadTime)
    FROM
      UNNEST(hits)
    WHERE
      page.pagePath = '/' ))/SUM((
    SELECT
      SUM(latencyTracking.pageLoadSample)
    FROM
      UNNEST(hits)
    WHERE
      page.pagePath = '/')) AS pageloadspeed,
  SUM(totals.newVisits) AS new_,
  SUM(totals.screenviews) AS PAGEVIEWS,
  SUM(totals.bounces) AS BOUNCES,
   sum(CASE
      WHEN device.isMobile = TRUE THEN (totals.visits)
      ELSE 0 END) mobilevisits,
  SUM(CASE
      WHEN trafficSource.medium = 'organic' THEN (totals.visits)
      ELSE 0 END) organicvisits,
  SUM(CASE
      WHEN EXISTS(  SELECT 1  FROM UNNEST(hits) hits  WHERE REGEXP_CONTAINS(hits.eventInfo.eventAction,'register$|registersuccess|new registration|account signup|registro')) THEN 1
      ELSE 0 END) AS NewRegistrations,
  SUM(CASE
      WHEN EXISTS(  SELECT 1  FROM UNNEST(hits) hits  WHERE REGEXP_CONTAINS(hits.eventInfo.eventAction, 'add to cart|add to bag|click to buy|ass to basket|comprar|addtobasket::')) THEN 1
      ELSE 0 END) AS ClickToBuy,
  SUM(totals.transactions) AS Transactions
FROM
  `project.dataset.ga_sessions_*`, UNNEST(hits) as h
WHERE
  1 = 1
  AND PARSE_TIMESTAMP('%Y%m%d', REGEXP_EXTRACT(_table_suffix, r'.*_(.*)')) BETWEEN TIMESTAMP('2017-05-01')
  AND TIMESTAMP('2017-05-01')
GROUP BY
  date,
  Country,
  display
ORDER BY
  visits DESC;

编辑:

我尝试从 FROM 子句中简单地删除 UNNEST(HITS) 命中作为 h,这给了我以下错误:

错误:无法在 [16:14] 访问类型为 ARRAY> 的值的字段 sourcePropertyInfo

我也尝试在子查询中使用它,如下所示:

(select h.sourcePropertyInfo.sourcePropertyDisplayName from unnest(hits) h) as displayname, 

并得到错误:

标量子查询产生了多个元素

【问题讨论】:

【参考方案1】:

由于您需要在点击级别计算多个值,因此可能取消嵌套字段 hits 是最好的方法。缺点是您丢失了会话级别的 totals 字段聚合,但您仍然可以解决它。

举个例子:

SELECT
  date,
  CASE
    WHEN REGEXP_CONTAINS(h.sourcePropertyInfo.sourcePropertyTrackingId, r'82272640') THEN 'MUG'
    WHEN h.sourcePropertyInfo.sourcePropertyTrackingId = 'Social' THEN 'Social'ELSE 'Website'
  END AS Property,
  geoNetwork.country AS Country,
  COUNT(DISTINCT CONCAT(CAST(visitId AS STRING),fullVisitorId)) AS visits,
  COUNT(DISTINCT(fullVisitorId)) AS Users,
  h.sourcePropertyInfo.sourcePropertyDisplayName AS display,
  SUM(CASE
      WHEN REGEXP_CONTAINS(h.page.pagepath, r'/') THEN h.latencyTracking.pageLoadTime END) / SUM(CASE
      WHEN REGEXP_CONTAINS(h.page.pagepath, r'/') THEN h.latencyTracking.pageLoadSample END) AS pageloadspeed,
  COUNT(DISTINCT
    CASE
      WHEN totals.newVisits = 1 THEN CONCAT(CAST(visitId AS STRING),fullVisitorId) END) new_visits,
  COUNT(CASE
         WHEN h.type = 'PAGE' THEN h.page.pagepath END) pageviews,
  SUM(CASE
       WHEN (h.isentrance = TRUE AND h.isexit = TRUE) THEN 1 END) bounces,
  COUNT(DISTINCT (CASE
        WHEN device.isMobile = TRUE THEN CONCAT(CAST(visitId AS STRING),fullVisitorId) END)) mobilevisits,
  COUNT(DISTINCT (CASE
        WHEN trafficSource.medium = 'organic' THEN CONCAT(CAST(visitId AS STRING),fullVisitorId) END)) organicvisits,
  SUM(CASE
       WHEN REGEXP_CONTAINS(h.eventInfo.eventAction,'register$|registersuccess|new registration|account signup|registro') THEN 1 END) AS NewRegistrations,
  SUM(CASE
       WHEN REGEXP_CONTAINS(h.eventInfo.eventAction, 'add to cart|add to bag|click to buy|ass to basket|comprar|addtobasket::') THEN 1 END) AS ClickToBuy,
  COUNT(h.transaction.transactionid) transactions
FROM
  `project_id.dataset_id.ga_sessions_*`,
  UNNEST(hits) AS h
WHERE
  1 = 1
  AND PARSE_TIMESTAMP('%Y%m%d', REGEXP_EXTRACT(_table_suffix, r'.*_(.*)')) BETWEEN TIMESTAMP('2017-05-01') AND TIMESTAMP('2017-05-01')
GROUP BY
  date,
  Country,
  display,
  Property

我对我们的数据集运行了它,它似乎工作正常。我做了一些改变:

删除了 PropertyMAX 操作并将其添加到 group by。 pageviews 被认为是 hit.type = 'PAGE' 的点击次数。但不确定屏幕浏览量是否相同。 在有进入和退出事件时计算反弹。 交易总数是基于交易 ID 的计数(希望您的数据集中也填写了此字段)。

【讨论】:

感谢@will 这是最好的解决方案。尽管这与 GA 中报告的指标之间仍然存在细微差异,但我不知道为什么 @AaronHarris 刚刚看到你的另一个问题,最后看到了这条评论。尝试在WHERE 子句中设置AND totals.visits=1。它可能会使结果与您在分析报告中看到的相同。 谢谢威尔。仍然会出现一些错误,但主要是跳出率的数量,查询中的跳出率比 GA 中的要高得多 虽然如果我只使用 totals.bounces 它似乎更接近,但我不知道它应该如何超级膨胀【参考方案2】:

您在最外层的 FROM 语句中将表格展平(即此处:

来自 project.dataset.ga_sessions_*, UNNEST(hits) as h)

您的所有会话级别维度,例如 device.* 或 totals.* 值(如 totals.transactions)已经汇总到会话级别,因此当您通过取消嵌套匹配来展平表格时,这些总计值会被写入多次有命中。例子: 假设一个会话中有 30 个匹配项和 2 个事务,因为您将匹配项展平/取消嵌套,所以您将剩下 30 行包含 totals.transactions = 2,因此当您对它们求和时,结果将是 60本次会议中的交易。 您的用户和访问不会因此受到影响,因为您可以区分它们,因此可以消除任何欺骗。

在我看来,如果你只是删除 ,UNNEST(hits) as h 如果你删除或调整这一行,你的查询就可以工作

h.sourcePropertyInfo.sourcePropertyDisplayName 作为显示

因为您已经在除此特定行之外的需要的地方取消了 select 语句中的命中。

【讨论】:

嗨@thomas C 我已经根据您的反馈编辑了我的问题,不幸的是我收到了声明的错误。感谢您的反馈 是的,您现在正在取消嵌套(从 unnest(hits) h) 中选择 h.sourcePropertyInfo.sourcePropertyDisplayName 作为显示名称),因此这将返回比原始数据集更多的行。您可以将其包装成 ARRAY() (即 ARRAY(select h.sourcePropertyInfo.sourcePropertyDisplayName from unnest(hits) h) )作为 displayname )或者您可以聚合数组的值(我认为 array_agg() 函数可能是帮助) 谢谢托马斯。如果我像你说的那样包装 ARRAY,那么它会要求我按点击数分组,然后它会给我另一个错误,你不能按 ARRAY 分组。如果我尝试在 ARRAY_AGG 中进行包装,它表示查询将起作用,但我得到相同的错误:标量子查询产生了多个元素 - 我是否遗漏了 ARRAY_AGG 的某些内容? 你能澄清一下吗?仍然不断收到类似的错误 试试这一行:array_concat_agg(array(select (h.sourcePropertyInfo.sourcePropertyDisplayName) from unnest(hits) h)) as displayname 并按部分查询从组中删除 display(/displayname) .这应该运行,希望它以某种方式接近你想要的。【参考方案3】:

在 UNNESTing 一个数组之后,使用 MAX() 代替 SUMMing 它们以报告会话级矩阵:

使用:

MAX(totals.screenviews) AS PAGEVIEWS, MAX(totals.bounces) 作为反弹, MAX(totals.transactions) AS 事务 ... ...

代替:

SUM(totals.screenviews) 作为 PAGEVIEWS, SUM(totals.bounces) 作为反弹, SUM(totals.transactions) AS 事务

这应该可以部分解决您的问题。告诉我进展如何?

【讨论】:

【参考方案4】:

我认为William Fuks的查询中计算的跳出率要高得多的原因如下

WHEN (h.isentrance = TRUE AND h.isexit = TRUE) THEN 1 END) 反弹

似乎 isEntrance 和 isExit 只发生在 PAGE 命中,因此不考虑事件。因此,跳出次数过多是由于页面上可能发生了一个或多个交互事件的单个页面浏览量。

【讨论】:

以上是关于使用 BigQuery 提取命中级别数据时,Google Analytics 指标被夸大了的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 在同一查询中展平 GA 会话和命中级别字段

BigQuery 会话和命中级别的理解

Bigquery 仅更新部分页面路径

unnest 是不是始终在 Bigquery 中按命中数的升序显示数据

如何在bigquery中以最少的数据库命中执行多个sql

在 BigQuery 中的一个会话内或多个会话内查找事件时遇到问题