BigQuery/Firebase 查询事件,按用户属性排序
Posted
技术标签:
【中文标题】BigQuery/Firebase 查询事件,按用户属性排序【英文标题】:BigQuery/Firebase querying events, order by User Property 【发布时间】:2016-10-19 08:08:36 【问题描述】:我将我的 Firebase 项目连接到 BigQuery,并在今天收到了所有昨天的事件。
我有一个具有整数参数的用户定义事件。 以及字符串类型的用户属性“user_job”(例如“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 运行得更快,但这可能是随机的机会(而且 google 对数据收费,而不是时间)。 尽管如此,我还是将 Elliots 的答案标记为最终答案,因为根据文档,标准 SQL 是推荐的答案。 我仍然不知道这一切与 UDF 相比如何,可能会对其进行测试。
更新 2: 我使用 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 |
*请注意,时间可能是一个不好的指标,因为不知道谷歌数据中心在给定时间的繁忙程度。最后,处理的数据越少,成本就越低。我还是把时间加进去了,也许有点用处。
【问题讨论】:
我现在使用用户定义的函数让它工作。循环遍历所有用户属性和所有事件。我不知道这是否正确,并会在月底看到它的成本。但它有效。 【参考方案1】:我建议使用 standard SQL 而不是旧版 SQL 进行此类分析,因为它使语义更清晰。用户定义的函数,尤其是在旧版 SQL 中,将比仅使用 SQL 更难维护且成本更高。
这是一个可能有帮助的示例查询。要运行它,请取消选中 UI 中“显示选项”下的“使用旧版 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_dim
和params
转换为行,逗号运算符取它们之间的叉积:
SELECT SUM(value.int_value)
FROM UNNEST(event_dim),
UNNEST(params)
WHERE key = "coins_awarded"
有关旧版 SQL 中的 FLATTEN
和标准 SQL 中的等价物的更多信息,请参阅迁移指南中的 Removing repetition with FLATTEN
。
【讨论】:
【参考方案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
这将获得按用户的语言偏好分组的平均奖励硬币数量。
【讨论】:
我使用 UDF 让它工作,该 UDF 发出一个包含语言和 coin_awarded 的新行。如果您将其与 flatten 方法进行比较,您知道哪个更昂贵吗? 这对我来说还是有点奇怪,可以说 event_dim.params.key = "something",因为 event_dim.params 实际上是一个包含多个键的 RECORD。 这个答案非常好并且有效。我将 Elliot 的另一个答案标记为正确答案,因为根据文档,推荐使用标准 SQL。我对这两种解决方案都投了赞成票。以上是关于BigQuery/Firebase 查询事件,按用户属性排序的主要内容,如果未能解决你的问题,请参考以下文章