什么包括伟大的数据团队?

数据团队很难雇用。工程师供应量低,需求量高,Resumés难以冒险,而不耗时的电话/编码屏,而且经常没有旺’资源可以很难找到人们对您的产品充满热情。作为招聘经理,您可能很幸运能够负担专业招聘人员的服务。但是,招聘人员通常会向您发送完全不合适的候选人。

一个非常友好的招聘人员,我在纽约市中心,我前几天喝了咖啡,讨论这些行业问题。我们同意如果我们定义了构成大型数据团队以及角色实际意味着什么,那将是有用的。

我应该先雇用谁?他们如何一起工作?

  • 数据分析师
    • 您在雇用数据团队的目标可能是商业洞察力,并达到您的行动主要是数据(而不是直觉)驱动的一点。为此,有能力的数据分析师是您的起点。值得庆幸的是,数据分析师提供丰富的供应。具有激情挖掘见解和定量或半定量(例如ECON)背景的新群’太难找到。在高端,您可以在SQL中找到具有经验的人以及相对新的BI工具,如Looker。如果您有预算,75%的工程任务可以遇到的工程任务可以通过诸如段的即插即用管道工具来解决。大多数标准商业见解– “昨天/上个月发生了什么?”, “what’在我的客户群中是一个欠缺的人群吗?”可以在没有昂贵的数据科学家的情况下回答。
  • 数据工程师
    • 在某些时候,您的数据库和查询将变得太慢。你’LL还要刮擦数据源或使用No-One在段中构建连接器的API。也许你’LL希望有一些定制的销售额进行销售,那里’ll是一堆安全问题或那里’一些你想要刷新的一些巨大的查询,每天早上都会刷新,并在松懈中通知你。没有编程背景,您的数据分析师会感觉到他们的深度。这是您需要雇用数据工程师的时候。他们的专业知识确实位于将数据集获取到可以分析的位置。如果您的表格每月获得5000万场比赛,则查询将在一夜之间开始花时间,甚至可能会锁定。数据工程师可以缓解这一点– they 将能够优化数据库的索引’S用于快速查找的表,每天早晨刷新的有用聚合的有用聚合的物化视图,将自定义API连接到数据仓库,并且通常超出可由即插即用工具覆盖的。 
  • 数据科学家
    • 现在你’获得标准的商业洞察力,并从有趣的来源获得尺度’几乎肯定会对AI的警报歌曲感到好奇。如果您可以预测哪些客户会搅拌/转换怎么办?如果您可以通过行为培养客户群,该怎么办?具有主管数据科学家,这种下一级洞察力都是可能的。它们将在Python中使用机器学习库,尝试自动对您的系统中的客户和操作进行分类。他们可以预测未来(具有一定程度的准确度)并告诉您关于您的数据的故事。这将涉及使用数据工程师提供的大型数据集。一旦这些见解已经浮出水面,它们就会有一个培训的模型,可以保存到磁盘并刷新。但是,如果需要每天刷新,那么添加到数据分析师甚至销售人员可以阅读的表格中的那些见解?然后,您需要返回数据工程师,并让它们设置后端系统来执行此操作。
  • 数据科学工程师,机器学习工程师
    • 有时,您的(可能更多的老学校)数据工程师将以100%管道和数据库管理员专注于实现您的数据科学家提出的Python的模型。对于此问题,您需要数据科学工程师或机器学习工程师。他们的专业知识正在部署,缩放和刷新数据科学家提出的模型。数据科学家应该完全专注于概率,调整模型参数和置信度分数;您的数据分析师应该关注更高的叙述,您的DS / ML工程师现在可以采取模型,并确保它快速提供您的见解,并使用干净,新鲜,正确的数据。
  • 可视化工程师
    • 如果看起来都没有什么?’有你想要的图表吗?如果您需要可视化网络怎么办?如果您的数据有16个维度和您’在散点图中耗尽了所有颜色,尺寸和形状选项?然后,您需要可视化工程师的非常专业的作用,以建立自定义可视化,并考虑更好的方法来实现数据分析师挣扎的洞察力。
  • 商业智能工程师
    • 这是一个暧昧的冠军–它们可以是数据科学工程师或数据工程师。

角色

标题 责任 工具/技术
数据分析师  基本商业见解 何处 / Tableau,SQL,Excel,Redash
数据科学家 更复杂的业务预测 Jupyter笔记本,Python,Scikit-Searning,Numpy,Scipy,StatsModels
数据工程师 得到“Big Data”到可以分析的点以及连接自定义数据源 SQL,Python,Scrapy,Spacy,Selenium,Kafka,气流,Luigi,Spark,AWS,红移
数据科学工程师或机器学习工程师 实施数据科学家’s models at scale SQL,Python,Scikit-Learn,Numpy,Scipy,AWS,Tensorflow
可视化工程师(罕见) 制作美丽的图形来增加每个人’s work looker / tableau,javascript,d3.js,highcharts,html

但为什么每个人都专注于数据科学?

数据科学是一种流行语,即一些用于代表任何适合数据工程和分析的人的流行语。最大的错误公司之一使得聘请了太多的数据科学家,而不是足够的数据工程师。最近,数据科学家们越来越容易雇用,因为许多原始数学家,化学家,统计学家和其他量化毕业都发现他们可以轻松地重新加入自己或参加3个月的训练营,并在初中雇用。但是,他们的模型和他们的见解可能是有限的’知道如何缩放/部署它们;他们将花费大部分时间清理数据集,而不是深入集中在隐藏内部的消息和预测。当然,作为一个大多数现在专注于数据工程的人,我偏见,但我会说每个数据科学家应该与至少1个数据工程师配对。我实际迁入数据科学的原因是我自己的工作真的是必需品。

我希望本指南在今天解释时取得了成功’S数据团队。如果您对如何改进它有任何想法,请发表评论或发送电子邮件。

开放采购变点–用于数据库监控的方便工具

帧中的数据

在一个越来越多的初创公司 Frame.io.,我们拥有大量的数据,每月超过6700万场比赛。有效的分析至关重要,仍然是市场领导者,我们使用整个主机工具:

  • 哎呀 何处雷彩 and PS.equel.
  • 内部分析和查询并行化微服务
  • 自定义AI Slackbots我们为垃圾邮件/入侵检测和销售引导探测器构建

这意味着我们的数据仓库正在不断击中大量查询 - 都在Cron计划和探索我们数据集的员工上。

卷问题

管理此卷的查询可能是艰难的。

  • PostgreSQL表可以锁定 - 尝试换/删除表格,而其他人查询它,例如,将导致它们锁定。理想情况下,分析表应该只能逐步更新,但有时设计约束阻止这一点。
  • SQL GUI可以随机超时,并且它很有用来快速检查DB,以查看它们是否仍在运行。
  • 使用 a combination of screen and PS.ql to run queries in the background requires monitoring. Dima is great for that.
  • 没有大百万行表的限制的意外选择可能会崩溃SQL GUI。
  • 有时候很大的查询就不是你想要的。 pl没有取消按钮,托管GUI如Redash和Looker都有取消按钮,通常对长时间运行查询无响应。

迪瓦

为了帮助解决此问题,我构建了一个名为DIMA的小命令行工具。这最初站在“数据库完整性监控”&分析“,但现在它只是真正的”Dima“。它非常简单,结果已经超级有用,所以我得到了开源的确定。

Dima is a Python script that basically lets you quickly summarize or inspect the pg_stat_activity internal table in Postgres via the psycopg2 library. If you want to kill a query it will call pg_terminate on the PID.

退房 //github.com/Frameio/homebrew-dima.

安装 using pip install dima-db or 酿造 tap Frameio/homebrew-dima && brew install dima

命令

dima  - 运行查询摘要

dima show [PID] -INSPECK特定的运行查询

dima rm [-f] Some PID or Keyword  - 杀死查询/查询

我们如何在Frame.io上注册

归因于800M点击600K用户

在 Frame.io. we use 分割 为应用程序使用分析供电。我们的应用程序和我们网站上的每一个动作都可以通过拨打诸如“注册“ 或者 ”查看视频“。

此数据对于我们的A / B测试和分析至关重要。结合细分的伟大一体化与服务 清单,我们可以通过公司信息丰富档案,然后在用户访问任何服务的首次访问我们的首次访问中。这些数据让我们确定哪些博客作者推动了最高的LTV客户,尤其州的潜意识会产生最不粘的用户等。

我们利用各种不同的增长渠道 - DRIP电子邮件广告系列,Facebook,YouTube,Twitter,Google AdWords以及它们都有独立的平台,其中一些不同步到我们的数据仓库中。需要一个系统来均匀化这些信息,以便在一个地方分析客户,渠道,广告系列和中等。

归因确实是拥有公司的市场适合360度的观点,以及简单地向正确的受众解释其服务的能力。

规划归因系统

概念上的归因非常简单 - 只要找到用户的ID并提取UTM的第一个结果?但是,在您可以到达用户来自的那样的单行数据之前,有很多考虑因素:

  • 即使具有很大的索引,每天在数百万行中搜索数千个用户,并维护这些行后面的分区和索引可以是数据库上的大负载。
  • 当用户第一次来到该网站时,他们没有user_ids - 但是段分配的anonymous_ids。用户ID仅与用户关联,一旦用户创建帐户和“i凹陷Y“呼叫是使用Anonymous_ID和User_ID进行的。有时我们会从一年前从一年多发上发现一个用户的Anonymous_ID。一旦我们拥有用户的全局ID(从我们的系统分配),那么我们必须在被分配的ID之前填写所有匿名会话。
  • 我们必须在注册之前会促进每组用户操作和汇总属性。 sessionization是将离散用户事件聚合到页面加载的运行过程中,间隙不超过20分钟。这使我们能够做出像分析访问的整体意图并将其批量归类。重新调整化涉及庞大的嵌套窗口函数和别名表,通常相同的用户具有多个历史anonymous_ids来合并。
  • 我们将希望维护一些快速查找表,以便有用 - 用户会话计数,有用的会话,也许是一些聚合,看看我们如何在可视化工具中做 何处.
  • 还要注意,该段实际上有一个本地人 归因 系统使用代码段安装;但它无法在您安装之前重新回头 - 我们有数据返回2014年。

实施阶段

系统设计在以下8个查询组/阶段结算:

  1. 查找现有会话化数据中的最新时间戳
    1. 从段曲目表中获取所有最新的访问数据
    2. 使用最新的月分区合并此数据,其中一些代码检查列仍然相同(可以添加新字段)。
  2. 会话化最新分区(可能会在过去24小时内重叠,因此请确保介绍间隙)
    1. 使用任何新识别的Anon /用户对更新别名表。
    2. 返回所有历史会话和重新别名 - 即,交换任何新识别的User_ID的匿名ID。
    3. 重新调整所有历史会话,因为邻近的会话可能历史上的匿名ID,但现在是相同的user_id
  3. 添加额外列以指示用户是否在会话中注册
    1. 将生成的会话表合并到单个all_sessions表中
    2. 为有用的会话创建查找表 - 这是第一个会话,并且仅每个用户的注册会话
  4. 创建一个有用的属性表,其中包含UTM参数预先提取和会话计数
  5. 重新索引任何表并检查分区是否按顺序(尤其是在新月间隔内)。

表结构

表/模式:

  • 混叠
    • 众所周知
  • 会话
    • 归因
    • all_sessions.
    • 有用_sessions.
  • Sessions_stages
    • all_tracks_2018_01
    • all_tracks_2018_01_aliased.
    • ALL_TRACKS_2018_01_RE_MERGED.
    • ALL_TRACKS_2018_01_SIGNUP.
    • …etc
  • 分区
    • 应用程序_tracks_2018_01
    • 应用程序_tracks_2018_02.
    • 应用程序_tracks_2018_03
    • …etc

最终会话中的列.Attribution表(许多只是Quanc ange Quickegation的Quick查找,并且该表是大量索引的):

  • alias_id.
  • session_count_before_signup.
  • signup_timestamp.
  • blog_url.
  • first_page_ever_visited.
  • 第一触摸(即与任何Frame.io属性的第一次交互)
    • 时间戳
    • 来源,广告系列,中等,推荐人
  • 最后一次触摸(即注册前的最后一次交互)
    • 时间戳
    • 来源,广告系列,中等,推荐人
  • 第一个归属触摸(如上所述,但使用付费推荐人)
    • 时间戳
    • 来源,广告系列,中等,推荐人
  • 最后一个归属的触摸(如上所述,但使用付费推荐人)
    • 时间戳
    • 来源,广告系列,中等,推荐人

部署和监控

系统需要大约1.5个月才能获得运行,并且是大约800行代码(Python,SQL,shell和Yaml)。

云计算生态系统,如AWS,Google Cloud和Azure,使得可以像这样直截了当地部署微服务。代码是occkerized(开启的 高寒)并部署在一个 ECS FARGATE. 簇。新构建正在处理 Codepipeline.,它监视归属GitHub repo。底层数据库是 极光Postgres..

这个系统每天早晨需要4个小时才能运行,并且可以遇到潜在的表慢化或不可用的困难。要缓解此方法,每个查询都有2小时重试系统。

性能已登录 AWS. CloudWatch.,同步到 DATADOG.。如果重试后任何查询完全失败,那么a PageRduty. ping被送到我的手机。

结果

  • 很酷的统计数据 - 71%的用户在他们的第一届会议中注册!
  • Frame.io.(我们的段轨道表分区组合的行计数)已经采取了8亿份行动 - 我们现在拥有超过60万用户。
  • 我们不再需要挖掘特定平台(例如Facebook业务,Google Analytics),而是在一个地方进行所有分析,并且可以在Looker中显示它!
  • 我们可以通过简单的SQL组轻松计算每个广告系列或频道的平均LTV。
  • 我们可以衡量源的粘性 - 例如。我们的YouTube广告是否给了我们持续很长时间或迅速搅拌的客户?
  • 作为一个勇气检查,我们要求用户报告他们听到的框架.IO(50%直接,14%YouTube,10%Facebook),并且这些数字与我们的“第一触”列完美匹配。

我们从哪里开始?

  • 该归属系统只是实际分析背后的管道。当我们必须做出更多哲学决策时,它变得更加困难。我们如何决定如何归因于“多触”用户?例如。如果用户在一个博客文章上首先触摸,并且几个月后的最后一个触摸,那么谁获得了信贷?
  • 我们现在正在密切监测性能,它在大约4个小时内运行。然而,我们的交通每月都会增加大量的巨大量 - 这最后会更长时间?值得庆幸的是,除了最后一级,系统很容易并行。

 With thanks to Kyle Gesuelli and Ammon Brown for proof reading, edits and suggestions. I originally posted on the Frame.io blog at: //medium.com/frame-io-engineering/marketing-attribution-at-frame-io-8c2dbde14b37

避免使用顶级导入的多个读数

最近一世’一直在使用需要导入大型JSON定义文件的各种应用程序,详细介绍复杂的应用程序设置。通常,这些文件是CodeBase中的多个辅助模块所需的。无论它使用多少辅助模块,都只导入此类文件的软件工程点的所有原则。

我对此的本能方法是在文件中读取主处理程序模块,然后将其内容传递为类初始化参数:

问题是,如果您有一个精心的导入进程,以及要导入的多个文件,它可能会开始看起来凌乱。我最近发现这个多个初始化参数方法是’实际上是必要的。

在Python中,您实际上可以在两个辅助模块(模块1和模块2)中导入相同的设置加载程序模块,并且Python只会加载一次:

现在,当我们在终端中进行测试时:

尽管有呼唤 进口 放ings_loader.  两次,Python实际上只调用一次。这是非常有用的,但如果您实际上想要两次导入文件,也可能导致头痛。如果是这样,那么我将在内的设置导入器 __在里面__()  每个类别x并将其实例化两次。

在代码中深入嘲笑API呼叫

与任何积极开发的(Python)编码项目,您’RE和您的团队将运行相同的测试,有时每周数百次。如果有’s HTTP请求在那里的任何第三方源,这可能会导致问题。 API调用可能是费用,过度刮擦相同的源可能导致IP黑名单,并且呼叫可以减慢整个测试过程,将额外行李添加到代码部署过程中。

要解决此问题,我们可以使用python’S模拟库。模拟对于创建虚假函数调用,假类和其他伪伪对象非常有用,这可以返回假值。在大多数情况下,在测试时,您实际上只是测试应用程序如何解析数据而不是第三方服务的可靠性。 API.’响应通常是相同的。模拟可以让你模拟API’响应并解析其数据,而不是实际使用每次都要打电话。

It’设置得非常棘手,所以我以为我会写一个教程。设置的情况有一些组件,但我’请尝试并尽可能地解释它。让’s说有一个提供一些有用的API响应的服务。那里’S一个网站,httpbin,由kennethreitz设置,以测试HTTP库,我们将在这里使用。退房: //httpbin.org/ip。内容如下:

让’S表示我们的程序希望抓住IP地址 起源 field. Yup –一个相当突触的计划,但这将是对你的许多情况都有类似的’ll encounter.

这里’S完全过度创作的类以获取此服务的数据。当课程初始化时 __在里面__,它创建一个指向httpbin的base_url变量。主处理函数是 得到_ip. 功能,简单地抓住该字段’■内容。这首先打电话给 api_call. 哪种用途 请求 抓住HTTP数据。

要仅运行此代码(在Python shell中):

如果我们想嘲笑怎么办 请求?模型模块文档尚不清楚如何在类中瞄准特定功能。事实证明了最简单的方法不是 魔术师 或者 返回_value. 但是,要使用反直直的命名“副作用”特征。这是测试模块预嘲笑:

正如您所看到的,这是一个标准的测试集,以检查 IP._GRABBER. 函数返回有效的ISH IP地址。它如下:

但是,这里的问题在于每次运行测试时都会调用实际的API。停止这一点,让’s集成模块模块:

这里 we’ve:

  1. 导入模块模块。注意:如果您收到错误“wraps” in the “six”模块然后几乎肯定是因为您有多个安装六个或模拟,并且需要删除一个。
  2. 创建一个假函数 fake_get. to replace 请求 和。这实际上只是返回“123”为此,所以你可以看出它是如何使测试失败的下面。
  3. 在test_ip_grabber函数周围添加了mock.patch包装器。这里非常重要的是指定函数名称,因为它在my_module中导入,而不是它在python标准库中出现;即我们正在做“my_module.get” rather than “requests.get”. The 副作用 = 然后用我们想要的任何功能替换它。
  4. 现在必须将副作用指定的假函数添加为函数的参数。

运行这个,我们得到:

嘲笑’s 副作用 已更换 请求 - 要使这个通行证,只需更换  返回 {'起源': '123'} with 返回 {'起源': '123.123.123.123'}  and run again:

测试通过和零HTTP流量! -

在ifup / ifup-eth中修复Django / Vagrant错误

我通常使用本地Vagrant实例测试Django项目。 Vagrant创建一个运行Django项目的虚拟机,该项目即时识别对代码的更改。但是,我最近正在运行测试,并且VM突然开始输出错误消息,如下所示。注意:I.’ve缩写了这些终端输出的一些部分。

(滚动到此帖子的底部以跳到解决方案)

没有翻译文件?一世’从来没有听说过他们。认为它可能是一个随机错误,我试图再次运行测试并得到:

我尝试退出实例并获得I / O错误:

尝试再次陷入VM中:

有时是“把它再次打开”解决方案可以工作,所以让’s尝试vagrant重新加载:

这回流超时错误。错误似乎与身份验证有关,但它’不是整个故事。 VM根据全局状态运行,尽管没有正确设置,这有点奇怪。

我也跑了一个 GUI叫VirtualBox. 这有时便于可视化笔记本电脑上的所有VM。检查那里,似乎也存在–所以全球现状不是’t lying to us. Let’s try halting it:

这次强制关闭。到目前为止调试此错误是’进展顺利。它是完全奇怪的,因为VM事先正常工作。在产生相同的超时后,vagrant起来:

让’s尝试完全销毁Vagrant实例….

从划痕开始:

那’一个非常奇怪的错误。也许有些东西失败了?

显然它仍然创造了VM。 sching融入它:

奇怪地没有文件!还没有东西’t startup properly.

此时我有点沮丧,并开始谷歌这个错误。我能找到的最相关的博客文章是Mike Berggren’s solution here: http://mikeberggren.com/post/100289806126/if-up。他修复了这个问题并报告:“我会给你剩下的血腥细节,但足以说,我们最终避免了从主机中检查并运行同样的命令。它回到了另一个MAC地址声称所有权“。这是否意味着他从字面上评论了要检查的代码线?他可能有一个非常不同的问题和我’没有Dev-ops专家,但也许在那里’s a better solution –也许检查是有原因的。

让’请回顾之前提到的网络错误:

CAT VARMANT文件,它显示了相同的IP地址。这意味着始终分配了这种特定的流浪汉。如果这是唯一的实例,则此虚拟网络上的其他内容如何使用它?我的Mac里面的东西与它相互冲突。

我们可以检查看看是什么’S通过检查运行进程(除了全局状态和VirtualBox之外)何时跑(除了:

啊哈!他们实际上有2个。让’s摧毁我们之前创建的非功能空白VM,看看是否有任何已更改:

是的,它已经走了:

使用kill -9 [pid]删除它。

现在让步’s尝试重新创建VM:

有用!

结论:

  • I’仍然不确定为什么这首先发生这种情况。开始的错误完全是蓝色的– I’d已经在没有问题的情况下运行了几个星期的VM。也许这是我的事实’D一直在运行这么久吗?
  • VAGRANT GLOBAL-Status和VirtualBox似乎不完全准确地报告运行VM,所以肯定会检查所有正在运行的VBOX流程使用PS并删除任何DOTN的附加费用’t正确关闭。这让我想起了–全局状态的Prune选项(//www.vagrantup.com/docs/cli/global-status.html)可以修复持久的旧条目。

非常感谢Tony(http://blog.tonns.org/)为了帮助工作这个问题!

将MongoDB FindOne()功能扩展为findAnother()

鉴于新的MongoDB实例与之合作,它通常很难理解结构,因为与SQL不同,数据库本身就是较少的模式。流行的初始工具是 品种(找到所有可能的字段并告诉您在DB中的类型,出现和百分比。

但是,看通常很有用的是,也可以看出这些领域的内容。为此,您可以使用 寻找One(),抓住似乎是从集合中的最后一个插入的记录,并将其漂亮打印到终端。这很棒,但有时您希望看到多个记录以获得更好的外地内容。在这篇文章我’LL向您展示我如何扩展Mongo来做这件事。

(假设你’已经安装了Mongo和Git– I use  酿造 安装 蒙古 from the 家用包装经理 我的Mac上的Xcode带来了git)

首先,让’得到了蒙古的副本’s code:

这将在文档中创建一个文件夹,所以让’s inspect it:

那里’在那里有很多文件,它需要一段时间才能找到FindOne()函数所在的位置。 GitHub.’S存储库搜索返回太多结果,所以让’使用UNIX文件搜索。 MongoDB以JavaScript(编译)编写,因此我们需要查找像这样的函数定义 寻找One = 功能( or 功能 寻找One( . Try this search:

这里的两个旗帜是 -l  (小写l)显示文件名,以及 R  哪个搜索所有子目录。终端的FullStop是为了搜索当前目录。您可以看到它找到了一个javascript文件,“collection.js”。如果在文本编辑器中打开它,则列出FindOne()函数:

此代码也可以在MongoDB Github页面上找到: //github.com/mongodb/mongo/blob/master/src/mongo/shell/collection.js#L207

我们的功能将扩展FindOne,而不是找到另一个记录。这可以通过做一个来实现“find”使用完全相同的代码,但随后跳过随机数量的记录。跳过金额必须小于所列出的记录数,这不幸意味着我们必须运行两次查询。首先要计算结果的数量,而第二个实际跳过数量。

复制FindOne函数并将其重命名为findanhother,在顶部有这些行:

  1. 获取查询返回的记录的计数(存储在Total_Records中)
  2. 从1到计数的范围内生成随机数(存储在rancornumber中)
  3. 再次使用该号码作为跳过(存储在光标中)

在javascript中生成随机数在javascript中有点模糊,但我发现了一个有用的StackOverflow tip才能做到这一点: http://stackoverflow.com/a/7228322 in one line. I’m used to Python’s ultra simple randu.randrange().

让’首先测试这一点。你’请注意,所有代码都可以在Mongo返回’s javascript shell:

您实际上可以在终端中替换此代码,但它赢了’一旦关闭它,T将保存。尝试使用Hello World替换FindOne:

您可以通过在第一个等式之后复制所有内容来首先在终端中测试我们的新功能。打开MongoDB shell到您最喜欢的DB和类型 D b.我的收藏.寻找One =  然后粘贴在功能中。尝试调用它,并且每次都应该返回不同的结果。

让’S补丁MongoDB现在使用我们的功能。我们必须从我们刚下载的来源中汇编Mongo。

  1. 保存使用新的FindAnother()函数刚刚编辑的Collection.js文件
  2. 确保安装了C ++编译器。一世’使用使用的GCC进行使用  酿造 安装 GCC.
  3. 检查处理器有多少核心。根据谷歌,我的2.7 GHz Intel I5有4个核心。
  4. 在同一终端窗口(仍然在Mongo文件夹中),键入: 骗子 -j4 蒙古  and press enter. The 4  这是我拥有的核心数量,并严重速度速度。 骗子  是一个处理汇编和放置的程序 蒙古  在此结束时,指定我们只想修补蒙古’s client.

你’LL看到大量的绿色文本,因为Scons检查一切,然后:

它编制了!我们现在必须使用已修改的版本取代现有的Mongo应用程序。让’s do a unix find:

我们希望替换/ usr / local / cellar /(brew安装它的Mongo应用程序)。让’然后备份它然后复制:

现在,将MongoDB Shell打开到您最喜欢的DB:

 Caveats:

  • 这可能会非常缓慢,因为它必须运行两次查询。但是,通常我不’t将超级征税查询添加到FindOne()。
  • 如果使用Brew重新安装/升级Mongo,则可以替换此功能–他们经常发布新版本。

改进

  • 一种用作Python生成器的函数,保持状态和向前循环,直到它到达记录集的末尾。这将解决上面的任何缓慢,但不那么随机。

将HTML表转换为Excel下载HTTP响应:用于慢慢OLAP DB连接的黑客

概述

Zenko. (“Good fox”日本人)是一个报告系统(在此处查看github上的代码) 一世’在Mozilla的最后几周内创作。基本上我的非技术同事由Tableau遭受沮丧(“Heck是内部连接和外部连接之间的区别?”)我决定为它们创建一个简单的仪表板界面。

它是一个简单的bootstrap前端到包含广告系列统计数据库的数据库 赞助瓷砖。您可以向每个瓷砖或客户/伴侣深入钻取,并按照区域设置,国家和日期等物品枢转。

Zenko.’s堆栈(高到低电平)

一个新的功能

加载其中一个分析页面时,将显示一个表。我的同事希望能够将数据下载到Excel。我提出了4种可能的方法来实现这一点:

  1. 只需重新运行查询,将结果格式化为后端的CSV,保存它和Window.Open()文件位置。
  2. 自动从每个分析请求服务器请求中保存数据,并定期清除旧文件。
  3. 使用类似JavaScript库 ExcelBuilder.
  4. 将数据发送回服务器,格式化它,然后通过iframe返回客户端

哪个是最好的解决方案?

  1. 这是有问题的,因为我们的粘附点是查询速度。红星数据库是一个 OLAP栏导向数据库,并仅申请。这意味着它难以快速地添加数据,但相当慢(通常是6秒)来查询。是的,它正在处理数十亿行,如此可忘记的,但在用户体验等待这么久的方面并不是那么伟大。用户并不是 ’当他们已经等待了6秒的时间来分析他们已经进行了数据。
  2. 这听起来像它最终可以在客户端上存储很多数据,但它可以很好地工作。在安全方面,我’m不确定数据应该在用户身上徘徊’但是,虽然,PC不可否认。
  3. 这没有’t work out so well –在Firefox中,该文件不正确地命名。在未来,我’d想根据分析参数命名文件。<client>-<date>-<country>.xls
  4. 这是最奇怪的解决方案,但它有效!烧瓶在本地运行,因此它实际上非常快。没有巨大的jQuery / JavaScript复杂功能,文件权限以及您可以在服务器上轻松操作数据的事实也很好。

解决方案4.

这个过程如下“Download for Excel” button is clicked:

  1. 使用JavaScript引用HTML表并将其转换为数组数组
  2. 将iframe附加到dom
  3. 将一个表单附加到帖子操作和隐藏字段到iframe
  4. 将表内容插入隐藏的字段’s value
  5. 提交表格
  6. 让 Flask receive the POST request and format the information as a CSV
  7. 使用包含CSV的文件附件返回HTTP响应

让’s implement it

那里 were various ways to do this in JQuery with 迭代.每个()  但我遇到并发症并简单地使用.Children引用细胞更容易。

然后(本地运行)瓶瓶将收到邮寄请求 /download_excel. . Let’s set up the route:

现在,当用户点击按钮时:

下载excel的链接

他们立即得到:

下载弹出窗口

对不起,我可以’t显示它在Excel中的样子,因为数据是n’目前公众。但是,所有代码都可用 在github上!

然而,一个奇怪的事情是表格并不是’T出现在检查器中(在Chrome或Firefox中):

在检查员看不见

虽然,您可以使用一些相当冗长的吸气器来访问它:

为什么.jpg.

未来的特色 

  • 这些文件可以名为比data.csv更直观的东西–也许是在URL中看到的各种东西的组合’s query string
  • 适用于较6行的桌子。这可以通过使用不同的分隔符来串励阵列来轻松完成,例如“###”.
  • 如果有任何优势,则创建.xls文件而不是csv

在Firefox扩展中使用Web Workers

Web工作者允许您在Firefox等浏览器中运行代码。这是如何将一个构建为Firefox扩展,它与仅在页面上的正常创建一个略有不同。这样做的文件基本上是不存在的,所以希望你’ll find this useful.

请确保您的开发环境设置类似于那个 在我以前的帖子中描述。

工人如何工作?

  • /数据的工人/不直接连接到/ lib中的脚本/
  • 但是,它们可以通过向彼此发送消息进行通信
  • 这些消息仅限文本,所以可以包含序列化JSON,但没有别的
  • 你’请注意下面我们基本上只是在两个脚本之间播放消息

工人的代码

导航到/ data /目录并创建一个名为hello_world.js的文件

现在在那里粘贴以下内容(vim的新用户,按 i  to start typing and 退出  followed by :WQ.  to save):

这表明,只要工作人员从客户端收到消息,那么用单词发送回报“Hello” prepended.

这里有一个注:在工人,你可以’使用有用的功能  安慰.日志(“信息”) , instead use  倾倒(“信息”)

让’从主代码调用工人

让’返回给 /lib/  folder and edit the 主要的.JS.  文件,这是一个在扩展中运行的第一件事。

粘贴以下代码:

并跑步  CFX. 跑步 . You’ll注意一个凌乱的错误:

啊哈!关键线是:  参考交流: 工人 不是 定义 。这是因为Firefox Extensions使用称为Chromeborker的东西。我们需要通过粘贴在顶部的Main.js中导入这个:

并更改引用hello_world.js文件的行来调用Chromebooker:

好的,让我们’S试着再次运行它!尝试  CFX. 跑步 。 wtf另一个错误?!

关键线是:  畸形 脚本 Uri.: 你好世界.JS. 。这种密码错误是因为Firefox可以’还有进入任何东西 /数据/  文件夹。我们必须使用SDK的另一部分来启用它。

打开 主要的.JS.  并把它放在顶部:

现在我们可以使用该功能 自己.数据.URL.() 。将文件名放在第一个参数时,它将返回像这样的字符串  资源://jid1-zmowxggley0aaa -at-jetpack/test/data/whate_file.js. 在扩展的情况下正确地指的是它。修改工作者导入行,如下所示:

现在让步’使用重新使用扩展 CFX. 跑步 :

这是工作!工作者返回了这封信“你好 Matthew“.

常问问题

  • 这是什么 {符号}  mean?

这是:

基本上这意味着  要求(“铬合金”) 返回一个对象,我们只需要密钥引用的值“ChromeWorker”。这是一种非常简洁的方法,可以从未来派上派上用手的JavaScript对象提取物品。

  • 为什么工人现在被称为Chromebwayer?我们是否用谷歌浏览器做点什么?

这是一个命名巧合,与浏览器中的Chrome无关。在这种情况下,Chrome指的是Firefox Addon Internals。

为Firefox Extensions设置开发环境。

这是我用来创建简单Firefox扩展的方法。本教程是t的前兆他接下来是关于使用Web工作者的一个 (即允许代码在后台线程上运行)。

设置环境

We’重新需要Firefox Addon SDK。这是一个Python文件的集合,可以让您运行Firefox的测试(可选的空白)版本。要下载它:

现在提取它并删除tarball:

转到目录并启动特殊shell:

现在,您可以看到shell在括号中向提示(addon-sdk-1.17)提示了。这意味着窗口可能是填充文本的一半,所以我们可以使用命令减少它:

更清洁! -

设置扩展模板

既然我们有这个特殊的addon-sdk shell,请返回文件并为我们的扩展创建一个新文件夹。

这个特殊的shell包含各种有用的命令,所有这些都是如此  CFX. XYZ. 。有关他们的更多信息 这里。在这种情况下我们使用  CFX. 在里面

让’s检查创建的内容:

  •  lib  包含一个调用的文件 主要的.JS.  这是所有扩展代码的主要处理程序文件
  • 数据  是空的,但可以用来存储像工人(我们将来的工作者)或大数据文件
  • 测试  可以包含单位测试(很难设置但在以后测试驱动开发有用)
  • 包裹.杰森  包含有关扩展的元数据–版本号,创建者的名称,描述,许可等

您可以在main.js中开始编写代码,它将在浏览器中运行。完成后,使用  CFX. 跑步 to test it!

有关如何使用Web Workers编写Firefox扩展的下一个教程!