用于向mixpanel进行jql查询的流库
mixpanel-jql的Python项目详细描述
运行JQL的小型python库 对mixpanel的jql api的查询。从api返回的数据是 当它到达时自动解压缩,使其可用于 第一行到达后立即处理。这是为了避免缓冲 内存中的大型结果集。
安装
要安装mixpanel-jql库,只需在 您的终端:
pip install mixpanel-jql
简单示例
让我们简单地计算一下2016年5月每天的“X”事件数量。分组的关键是事件以YYYY-MM-DD格式发送到mixpanel的日期。通过将键指定为new Date(e.time).toISOString().split('T')[0],我们可以从事件的time属性中获取该值。
用这个库做这件事既简单又快捷。
fromdatetimeimportdatetimefrommixpanel_jqlimportJQL,Reducer,Eventsapi_secret='...'query=JQL(api_secret,events=Events({'event_selectors':[{'event':"X"}],'from_date':datetime(2016,5,1),'to_date':datetime(2016,5,31)})).group_by(keys=["new Date(e.time).toISOString().split('T')[0]",],accumulator=Reducer.count())forrowinquery.send():date=row['key'][0]value=row['value']print("[%s] => %d"%(date,value))# [2016-05-01] => 302# [2016-05-02] => 1102# ...# [2016-05-31] => 120
但如果我们只想计算独特的事件呢?也就是说,如果我们关心每天每个事件产生多少用户,而不仅仅是事件发生的总次数,那会怎么样?
对前面的代码稍加修改,我们就可以做到这一点:
query=JQL(api_secret,events=Events({'event_selectors':[{'event':"X"}],'from_date':datetime(2016,5,1),'to_date':datetime(2016,5,31)})).group_by_user(keys=["new Date(e.time).toISOString().split('T')[0]",],accumulator="function(){ return 1;}").group_by(keys=["e.key.slice(1)"],accumulator=Reducer.count())
我们将accumulatorkeyward参数替换为返回1的javascript函数,因为每个用户只被计算一次。group_by_user还将用户id添加到结果的键中。我们可以通过用e.key.slice(1)分割细节并重新计算来重新组合结果。
更高级的示例
假设我们要用属性“b”来计算所有事件“a”,即 等于2和等于“hello”的属性f。事件“A” 有一个属性“c”,它是一些随机字符串值。我们想要 结果按“c”值分组并计数,以查看有多少属性 “C”事件发生在2016年4月的每天。
frommixpanel_jqlimportJQL,Reducer,Eventsapi_secret='...'query=JQL(api_secret,events=Events({'event_selectors':[{'event':"A"}],'from_date':'2016-04-01','to_date':'2016-04-30'})).filter('e.properties.B == 2').filter('e.properties.F == "hello"').group_by(keys=["new Date(e.time).toISOString().split('T')[0]","e.property.C"],accumulator=Reducer.count())forrowinquery.send():date,c=row['key']value=row['value']print("[%s] %s => %d"%(date,c,value))# [2016-04-01] abc => 3# [2016-04-01] xyz => 1# ...
如果我们只想计算unique事件(即计算每个用户导致的 仅此事件一次),我们可以将查询更改为group by user,以 减少它们导致特定^{tt10}的次数$ 只有1个。
query=JQL(api_secret,events=Events({'event_selectors':[{'event':"A"}],'from_date':'2016-04-01','to_date':'2016-04-30'})).filter('e.properties.B == 2').filter('e.properties.F == "hello"').group_by_user(keys=["new Date(e.time).toISOString().split('T')[0]","e.property.C"],accumulator="function(){ return 1;}").group_by(keys=["e.key.slice(1)"],accumulator=Reducer.count())
为什么您的筛选器没有与&&联接?
我们还可以将.filter(...)方法组合成1个方法 通过这样做,.filter('e.properties.B == 2 && e.properties.F == "hello"')。 连续的.filter(...)表达式将自动&&。 你选择的表达方式是文体的。
那是什么东西?
Reducer类是为了方便起见,它包含指向所有 reducer函数(例如Reducer.count()返回 mixpanel.reducer.count(),和Reducer.top(limit)返回 mixpanel.reducer.top(limit))。请参阅代码以获取所有 减速器快捷键。
要编写自己的reducer,请确保包含完整的javascript 函数体(即function(){ ... })。
转换呢?
Converter类是另一种方便。
frommixpanel_jqlimportConverter...Converter.to_number('"xyz"')# Resolves to mixpanel.to_number("xyz")
关于“people”和“joins”的查询呢?
前面的所有示例都主要涉及jql查询 在事件上。此库还支持对人员和连接的查询 关于人和事。下面给出了如何工作的框架。
您只能使用events和people中的一个。join_params 仅当设置了events和people时才使用。
query=JQL(api_secret,events=Events({'event_selectors':[{'event':'...','selector':'...','label':'...'},...],'from_date':'<YYYY-MM-DD>','to_date':'<YYYY-MM-DD>'}),people=People({'user_selectors':[{'selector':'...'},...]}),join_params={'type':'full','selectors':[{'event':'...','selector':'...',},...]})....
支持哪些其他功能?
mixpanel似乎处于不断添加新函数的状态,而不仅仅是filter和map。 此库当前支持以下内容。请参阅代码了解它们的用法。
- filter
- map
- flatten
- sort_asc
- sort_desc
- reduce
- group_by
- group_by_user
如何查看发送到mixpanel的最终javascript是什么?
对jql查询使用str方法来查看 相当于javascript。
>>>str(query)'function main() { return Events({"event_selectors": [{"event": "A"}], "from_date": "2016-04-01", "to_date": "2016-04-30"}).filter(function(e){return e.properties.B == 2}).filter(function(e){return e.properties.F == "hello"}).groupByUser([function(e){return new Date(e.time).toISOString().split(\'T\')[0]},function(e){return e.property.C}], function(){ return 1;}).groupBy([function(e){return e.key.slice(1)}], mixpanel.reducer.count()); }'
这在调试过程中非常有用。
但是如果你想要什么呢真的可读吗?现在也可以使用.pretty方法了!
>>>print(query.pretty)functionmain(){returnEvents({"event_selectors":[{"event":"A"}],"from_date":"2016-04-01","to_date":"2016-04-30"}).filter(function(e){returne.properties.B==2}).filter(function(e){returne.properties.F=="hello"}).groupByUser([function(e){returnnewDate(e.time).toISOString().split('T')[0]},function(e){returne.property.C}],function(){return1;}).groupBy([function(e){returne.key.slice(1)}],mixpanel.reducer.count());}
注意事项
.filter(...)自动转换 括号'插入function(e){ return ... }。
重写该行为,并使用诸如properties.x 快捷语法,使用raw(...)包装器插入 你想在filter,map等参数中输入的javascript。
frommixpanel_jqlimportJQL,raw...query=JQL(api_secret,events=params).filter(raw(" function(e) {"" if (e.x > 3) {"" return true;"" } else {"" return false;"" }"" )")).filter('e.properties.F == "hello"')...
这个库不能在mixpanel的jql中轻松地表达所有可能的内容 语言,但确实试图简化一般情况。如果你有 使这个图书馆更方便用户的想法 潜在查询,请提交拉取请求或创建问题。
非常欢迎您的贡献!
在哪里可以了解有关mixpanel的jql的更多信息?
有关如何使用jql的更多信息,请参阅mixpanel的 文档here。