如何简化和扩展 Firebase 数据库上的 BigQuery 子过滤 event_params

Posted

技术标签:

【中文标题】如何简化和扩展 Firebase 数据库上的 BigQuery 子过滤 event_params【英文标题】:How to simplify and expand BigQuery subfiltering event_params on firebase database 【发布时间】:2020-11-27 10:56:11 【问题描述】:

我正在尝试进行 BigQuery 查询以从 firebase db 子表 event_params 中提取数据。 表 events_* 有一个事件列表,其中字段 event_params 是一个结构,其中包含keyint_value 形式的表以及在这种情况下未使用的其他字段。

例如,1 个单个事件可能有一个 event_params 列表,如下所示:

key    int_value
level  1
time   35
kills  10

我想按级别过滤事件列表,但从该事件中选择时间。我得到的解决方案是这样的:

select user_pseudo_id, x.value.int_value as time
from (

  select user_pseudo_id, event_params
  from `whatever.events_*`, unnest(event_params) as y
  where event_name = 'level_complete' and y.key = 'level' and y.value.int_value = 1

), unnest(event_params) as x
where x.key = 'time'

它适用于这种情况,但我有一些关于如何改进和使其发展的问题:

有没有办法在一个查询中简化这一点? 如果我想获取时间字段和杀人字段怎么办? (我能想到的唯一解决方案是复制查询并连接两个结果,但如果我想提取大量字段怎么办?)。 是否可以通过创建类似函数的函数来简化这一点,该函数返回像 Filter('level_complete', 'level', 1) 这样的结果表?

提前致谢!

【问题讨论】:

提供样本数据和预期结果 【参考方案1】:

这个资源占用较少,因为它不执行聚合:

select *
from (
  select 
    user_pseudo_id,
    event_name,
    (select int_value from unnest(event_params) where key = 'level') as level,
    (select int_value from unnest(event_params) where key = 'time') as time,
    (select int_value from unnest(event_params) where key = 'kills') as kills
  from `whatever.events_*`
  where event_name = 'level_complete'
)
where level = 1

【讨论】:

您能提供一个参考,说明子选择比 BQ 中的聚合便宜吗? 另外,公平的警告,如果一个键在任何行的event_params 中重复,整个查询将失败,Scalar subquery produced more than one element 嗨,完全同意。这不适合单行中有多个重复键的情况。资源消耗我通常在“执行详细信息”选项卡(“结果”旁边)中检查。 当您使用此类查询检查“执行详细信息”时,您是否看到子选择优于聚合?你的主张This one is less resource intensive because it does not perform aggregation的证据在哪里? 当然,只需比较聚合和子选择的执行细节。例如,对于您的答案中的样本数据,子选择的“计算”总数较少。【参考方案2】:

透视数据:

# start with some sample data
with data as (
select 1 as user_pseudo_id, 'level_complete' as event_name, [struct('level' as key, 1 as int_value), struct('time' as key, 35 as int_value), struct('kills' as key, 10 as int_value)] as event_params
UNION ALL
select 2 as user_pseudo_id, 'level_complete' as event_name, [struct('level' as key, 4 as int_value), struct('time' as key, 10 as int_value), struct('kills' as key, 1 as int_value)] as event_params
UNION ALL
select 3 as user_pseudo_id, 'level_complete' as event_name, [struct('level' as key, 6 as int_value), struct('time' as key, 30 as int_value), struct('kills' as key, 2 as int_value)] as event_params
UNION ALL
select 3 as user_pseudo_id, 'other_type' as event_name, [struct('bad' as key, 5 as int_value), struct('time' as key, 40 as int_value), struct('kills' as key, 3 as int_value)] as event_params
)
# This is the "code" part
select user_pseudo_id, event_name,
  max(if(params.key = 'level', int_value, null)) level,
  max(if(params.key = 'time', int_value, null)) time,
  max(if(params.key = 'kills', int_value, null)) kills,
  array_agg(distinct if(params.key in ('level','time','kills'), null, params.key) ignore nulls) as unexpected_keys
from data
CROSS JOIN unnest(event_params) as params
group by user_pseudo_id, event_name

或者,如果您更喜欢以这种格式创建转换表,请尝试fhoffa.x.pivot()

我一直将这种技术用于查询key 的所有唯一值的python 程序,然后使用适当的动态列创建VIEW。如果您的值是静态的,那么手写 SQL 会更简单。

【讨论】:

以上是关于如何简化和扩展 Firebase 数据库上的 BigQuery 子过滤 event_params的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 可扩展性:整个数据集上的观察者与多个观察者

BI工具定位,BI选型背景

如何使用带有平台、steam_id、event_name 过滤器的 bigquery 在 power bi 中编写查询以查找过去 28 天的 firebase 事件详细信息?

Word文档如何自动更新Power BI数据和图表?

如何在 Chrome 扩展 Manifest.json 中设置内容安全策略以使 Firebase 正常工作

webapp上的firebase帖子