通过 BigQuery 访问 Firebase 封闭漏斗中的结构和数组
Posted
技术标签:
【中文标题】通过 BigQuery 访问 Firebase 封闭漏斗中的结构和数组【英文标题】:Accessing Struct(s) and Array(s) in Firebase Closed Funnels through BigQuery 【发布时间】:2017-08-10 17:04:09 【问题描述】:本周我偶然发现了这个标准 SQL BigQuery documentation,它让我开始使用 Firebase Analytics 封闭漏斗。然而,我得到了错误的结果(查看下图)。在没有首先开始“Tutorial_LessonStarted >> Lesson = 1”之前,应该没有用户拥有“Tutorial_LessonCompleted”。这可能是由于各种原因。
问题:
-
使用用户属性 = "first_open_time" 是明智之举,还是使用事件 = "first_open" 更好。后一种实现会是什么样子?
我怀疑我可能没有正确深入到:事件 (String = "Tutorial_LessonStarted") >> 参数 (String = "LessonNumber") >> 值 (String = "lesson1")?
_TABLE_SUFFIX = '20170701' 上的过滤器如何工作,我读到这会更便宜。任何优化的代码建议都会张开双臂并投赞成票!
#standardSQL
SELECT
step1, step2, step3, step4, step5, step6,
COUNT(*) AS funnel_count,
COUNT(DISTINCT user_id) AS users
FROM (
SELECT
user_dim.app_info.app_instance_id AS user_id,
event.timestamp_micros AS event_timestamp,
event.name AS step1,
LEAD(event.name, 1) OVER (
PARTITION BY user_dim.app_info.app_instance_id
ORDER BY event.timestamp_micros ASC) as step2,
LEAD(event.name, 2) OVER (
PARTITION BY user_dim.app_info.app_instance_id
ORDER BY event.timestamp_micros ASC) as step3,
LEAD(event.name, 3) OVER (
PARTITION BY user_dim.app_info.app_instance_id
ORDER BY event.timestamp_micros ASC) as step4,
LEAD(event.name, 4) OVER (
PARTITION BY user_dim.app_info.app_instance_id
ORDER BY event.timestamp_micros ASC) as step5,
LEAD(event.name, 5) OVER (
PARTITION BY user_dim.app_info.app_instance_id
ORDER BY event.timestamp_micros ASC) as step6
FROM
`......`,
UNNEST(event_dim) AS event,
UNNEST(user_dim.user_properties) AS user_prop
WHERE user_prop.key = "first_open_time"
ORDER BY 1, 2, 3, 4, 5 ASC
)
WHERE step6 = "Tutorial_LessonStarted" AND EXISTS (
SELECT *
FROM `......`,
UNNEST(event_dim) AS event,
UNNEST(event.params)
WHERE key = 'LessonNumber' AND value.string_value = "lesson1") GROUP BY step1, step2, step3, step4, step5, step6
ORDER BY funnel_count DESC
LIMIT 100;
注意:
-
输入您的查询表FROM,即:
project_id.com_game_example_ios.app_events_20170212
,
我忽略了 funnel_count 和 user_count。
输出:
----------------------------------------------- ------------
自上述原始问题以来的更新:
@Elliot:我不明白你为什么说:- 确保带有第 1 课的事件在 Tutorial_LessonStarted 之前。
Tutorial_LessonStarted 有一个参数“LessonNumber”,其值为第 1 课、第 2 课、第 3 课、第 4 课。
我想计算漏斗中最后一步等于 LessonNumber=lesson1 的所有漏斗。
因此,应用于全新用户的第一个会话(又名:触发 first_open_time 的用户)的事件日志数据,答案将如下表所示:
View.OnboardingWelcomePage View.OnboardingFinalPage View.JamLoading View.JamLoading Jam.UserViewsJam Jam.ProjectOpened View.JamMixer Tutorial.LessonStarted(此参数“LessonNumber”的值将等于“lesson1”) Jam.ProjectPlayStarted View.JamLoopSelector View.Jammixer View.JamLoopSelector View.Jammixer View.JamLoopSelector View.Jammixer Tutorial.LessonCompleted Tutorial.LessonStarted(此参数“LessonNumber”的值将等于“lesson2”)因此,重要的是首先获取在特定日期拥有 first_open_time 的所有用户,并将事件构建到一个漏斗中,以便漏斗中的最后一个事件与事件和特定的参数值,然后从那里“向后”形成漏斗。
【问题讨论】:
你能看看我对这个问题的回答是否有帮助吗? ***.com/a/45575234/6253347。它有一个为选择列表中的特定key
检索string_value
的示例。
【参考方案1】:
让我解释一下,然后看看我是否可以建议一个查询来帮助您入门。
您似乎想要分析分析数据中的事件序列,但序列已经为您准备好了 - 您有一个事件数组。查看Firebase schema for BigQuery,event_dim
是相关列,除非我误解某些内容,否则这些事件是按时间排序的。如果要查看第六个事件的名称,可以使用:
event_dim[SAFE_ORDINAL(6)].name
如果事件少于六个,这将评估为NULL
,否则它将为您提供带有事件名称的字符串。
另一个观察结果是,您正在尝试同时分析 event_dim
和 user_dim
,但您正在取两者的叉积,这将导致行数爆炸,并且难以推理结果询问。要查找特定的用户属性,请使用以下形式的表达式:
(SELECT value.value.string_value
FROM UNNEST(user_dim.user_properties)
WHERE key = 'first_open_time') = '<expected property value>'
结合这两个过滤器,您的 FROM
和 WHERE
子句将如下所示:
FROM `project_id.com_game_example_IOS.app_events_*`
WHERE _TABLE_SUFFIX = '20170701' AND
event_dim[SAFE_ORDINAL(6)].name = 'Tutorial_LessonStarted' AND
(SELECT value.value.string_value
FROM UNNEST(user_dim.user_properties)
WHERE key = 'first_open_time') = '<expected property value>'
使用方括号运算符访问event_dim
中的步骤,我们可以这样做:
WITH FilteredInput AS (
SELECT *
FROM `project_id.com_game_example_IOS.app_events_*`
WHERE _TABLE_SUFFIX = '20170701' AND
event_dim[SAFE_ORDINAL(6)].name = 'Tutorial_LessonStarted' AND
(SELECT value.value.string_value
FROM UNNEST(user_dim.user_properties)
WHERE key = 'first_open_time') = '<expected property value>' AND
-- ensure that an event with lesson1 precedes Tutorial_LessonStarted
EXISTS (
SELECT 1
FROM UNNEST(event_dim) WITH OFFSET event_offset
CROSS JOIN UNNEST(params)
WHERE key = 'LessonNumber' AND
value.string_value = 'lesson1' AND
event_offset < 5
)
)
SELECT
event_dim[ORDINAL(1)].name AS step1,
event_dim[ORDINAL(2)].name AS step2,
event_dim[ORDINAL(3)].name AS step3,
event_dim[ORDINAL(4)].name AS step4,
event_dim[ORDINAL(5)].name AS step5,
event_dim[ORDINAL(6)].name AS step6,
COUNT(*) AS funnel_count,
COUNT(DISTINCT user_dim.user_id) AS users
FROM FilteredInput
GROUP BY step1, step2, step3, step4, step5, step6;
这将返回所有唯一的“路径”以及每个路径的不同用户的计数和数量。请注意,我只是在脑海中写下这个——我没有可以尝试的代表性数据——所以可能存在语法或其他错误。
【讨论】:
嗨,Elliot,感谢您抽出宝贵时间回复,抱歉我的评论延迟。我根据您的反馈更新了我上面的问题。我运行了代码,但没有收到任何输出。我只是不确定一段代码(我在上面的问题中说过)。该查询背后的核心思想来自:cloud.google.com/blog/big-data/2017/04/…这篇博文中的“第 2 步:计算以消费虚拟货币结束的旅程的用户”。让我知道您是否需要更多说明。再次感谢您的大力帮助:) 该部分由我的答案中的event_dim[SAFE_ORDINAL(6)].name = 'Tutorial_LessonStarted'
建模(当您可以使用数组运算符时,您不需要使用LEAD
)。我建议一次删除一个或两个条件并检查您收到的输出以查看问题所在。
感谢 Elliott,我注释掉了“first_open_time”子句,查看了 Firebase 日志,该值始终为“null”(将跟进 Firebase PO)。我得到了脚本的结果,并且 funnel_count 极低,为 20,user_counts 为零(与我预期的 7K 相比)。这让我想到了下一个问题:这个封闭的渠道是否明确地只给我在 TutorialStarted 结束的会话的渠道(纯应用程序退出),或者只是某个地方通过这个封闭的渠道并且不一定退出应用程序的用户会话到达 TutorialStarted-event 之后?
这是根据您的原始问题寻找第六个事件为TutorialStarted
的会话。如果您正在寻找最后一个事件,您可以使用event_dim[ORDINAL(ARRAY_LENGTH(event_dim))].name = 'Tutorial_LessonStarted'
。以上是关于通过 BigQuery 访问 Firebase 封闭漏斗中的结构和数组的主要内容,如果未能解决你的问题,请参考以下文章
如何从 firebase 云功能访问 bigquery 数据?
Cloud Functions for Firebase:无法访问 BigQuery