BigQuery / Firebase查询事件,按用户属性排序

时间:2016-10-19 08:08:37

标签: firebase google-bigquery firebase-analytics

我将Firebase项目连接到BigQuery,并收到了昨天所有的活动。

我有一个具有Integer参数的用户定义事件。 用户属性" user_job"类型为String(例如,#34; Pilot"," Mechanic"," Programmer",...) 我想知道用户作业分组的整数参数的平均值。

是否有提取该信息的SQL查询?

我知道SQL但我的问题是数据以某种方式嵌套在RECORD中,我不知道如何处理它。 如果每个事件一行,每个用户属性一列,我就不会遇到这个问题。如果是这样的话,我可以写一些像:

SELECT AVG( param ), user_job FROM table WHERE event_type = "my_event" GROUP BY user_job

但是用户属性在RECORD(数组?)中,并且RECORD中也有多个事件。

或许使用SQL查询是处理这类请求的错误方法。如果是这样,有人可以指点我的方向。 我看到BigQuery中有user defined functions。那么我应该创建一个用户定义的函数,将Firebase BigQuery行转换为如上所述的平面结构,这是正确的方法吗?

更新 我运行了Sara和Elliot的查询,处理的字节在两种情况下都是相同的(这是成本)。 Saras查询比Elliots跑得更快,但这可能是随机的机会(谷歌收费数据,而不是时间)。 即便如此,我还是将Elliots的答案标记为最终答案,因为根据文档,Standart SQL是推荐的答案。 我仍然不知道这一切与UDF相比如何,可能会对此进行测试。

UPDATE2: 我用UDF实现测试了它,它为每个round_completed事件发出了一个新行(语言,硬币)。与Sara和Elliot发布的仅SQL解决方案相比,它运行时间更长,处理的数据更多。

|_Solution___|_Time___|_Data Processed___|
|Sara        |2.1s    |399 KB            |
|Elliot      |2.4s    |399 KB            |
|UDF         |3.4s    |437 KB            |

*请注意,时间可能是一个糟糕的指标,因为未知谷歌数据中心在给定时间的繁忙程度。最终,处理数据的成本更低。我仍然把时间包括在内,也许它在某种程度上是有用的。

2 个答案:

答案 0 :(得分:3)

我建议使用standard SQL而不是遗留SQL进行此类分析,因为它使语义更加清晰。用户定义的函数,特别是在遗留SQL中,将比使用SQL更难维护和更昂贵。

以下是可能有用的示例查询。要运行它,请取消选中"使用旧版SQL"在"显示选项"在用户界面中:

SELECT
  user_properties.value.value.string_value as lang,
  AVG((SELECT SUM(value.int_value)
       FROM UNNEST(event_dim),
         UNNEST(params)
       WHERE key = "coins_awarded")) as avg_coins 
FROM 
  `firebase-analytics-sample-data.ios_dataset.app_events_20160607` t,
    UNNEST(user_dim.user_properties) user_properties
WHERE 
  user_properties.key = "language"
GROUP BY 1;

在此查询中,带有UNNEST(user_dim.user_properties)的逗号运算符会为重复的user_properties中的每个元素返回一行:

`firebase-analytics-sample-data.ios_dataset.app_events_20160607`,
  UNNEST(user_dim.user_properties) user_properties

在计算所有重复中int_value总和的子查询中,UNNEST用于将重复的event_dimparams转换为行,逗号运算符采用他们之间的交叉产品:

SELECT SUM(value.int_value)
FROM UNNEST(event_dim),
  UNNEST(params)
WHERE key = "coins_awarded"

有关旧版SQL中FLATTEN和标准SQL中的等效内容的更多信息,请参阅迁移指南中的Removing repetition with FLATTEN

答案 1 :(得分:2)

要完成此操作,您需要FLATTEN其中一个重复的字段。使用示例Firebase Analytics datasets,这里的查询类似于您尝试实现的内容:

SELECT
  user_dim.user_properties.value.value.string_value as lang,
  AVG(event_dim.params.value.int_value) as avg_coins 
FROM 
  FLATTEN([firebase-analytics-sample-data:ios_dataset.app_events_20160607], user_dim.user_properties)
WHERE 
  user_dim.user_properties.key = "language"
  AND event_dim.params.key = "coins_awarded"
GROUP BY 1

这可以获得用户获得的平均硬币数量,按照语言偏好进行分组。