Project

statlysis

0.02
No commit activity in last 3 years
No release in over 3 years
Statistic and analysis in Ruby DSL, just as simple as SQL operations in ActiveRecord.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Statlysis Build Status Documentation badges

Statistic and analysis in Ruby DSL, just as simple as SQL operations in ActiveRecord.

Usage

见下面的 成功案例 的配置文件 和 手把手操作示例

项目来由,理念,和使用说明

该项目起因是为eoe.cn做一套统计后台,而其构思来自于2012上半年做 Android优亿市场数据采集分析系统 时的一些经验和心得,在2013年上半年完成了架构和大部分代码,支持ActiveRecord和Mongoid两个ORM。下半年在阳光书屋加上了对Mongoid的MapReduce支持。

针对一般互联网网站的统计需求,都是把Google Analysis等分析网站的一段Javascript脚本放到网页底部,然后就可以看到网站每日详细的访问情况了。但是针对内部数据需求,比如每日注册用户量,这个一般就不可能开放给第三方去统计了,所以这就是statlysis的存在意义。

做过数据分析的人都知道其中的坑,比如有些是直接拿SQL跨多个表Join统计,每次有数据需求均执行一次完整的查询,随着数据量的增大,性能问题可想而知。

下面介绍如何用statlysis进行统计分析:

是否要 ETL(Extract, Transform, Load) 数据清洗

statlysis认为数据源一定要被ETL为简单几个维度的单层数据集,因为用户最后能看到和理解的也就是两三维的分析图表而已,所以从用户理解出发。

这里也需要注意如果当该数据表是可以直接支持统计分析的,但是数据量大,那么得加上相关索引,或者导入到另外的单表里(在ORM里可以在after_save等hooks里操作)再加索引。

流程

  1. 分析数据统计需求,画出包含对应维度的图表。
  2. ETL,参照 #是否要 ETL(Extract, Transform, Load) 数据清洗#
  3. Statlysis.setup { } 代码块里配置出页面需要的数据,注意得是单表的,类似没有跨表JOIN的SQL查询。
  4. 跑统计分析,比如 Statlysis.daily.run。此过程可以用cron定时来驱动,或者after_save等数据更新来驱动。
  5. 编写用于数据需求人员查看的HTML页面,其中统计数据可以用Statlysis.daily['code_gists'].first.stat_modelTimelyCodegist来直接查询。

尽量采用MongoDB来作为统计数据源

MongoDB作为NoSQL数据库,它是为 单collection 里读写 单个记录的整体 而优化设计的,并支持MapReduce并发来加快统计过程。

Success cases

  • eoe.cn各子网站的页面访问统计,和包含多个条件的数据库表每日数据统计,详情见 示例配置文件 ,按日期维度分。
  • 阳光书屋的学习提高班的关于做题情况的统计分析,详情见 示例配置文件 ,按班级维度分。

Features

  1. 支持Mongoid和ActiveRecord两种ORM,其中Mongoid以MapReduce方式统计,ActiveRecord基于纯SQL操作。
  2. 对统计结果进行SQL索引,以支持高效访问。
  3. 支持单行DSL配置,链式风格。
  4. 支持跨表统计,需结构相同,表名按日期分割。
  5. 依据统计需求自动配置统计结果的存储表,并支持条件查询,返回ORM统计表。
  6. 支持任意维度统计,其中时间维度可选。
  7. 单次统计里支持多个GroupConcat字段。
  8. 支持最近统计的时间。
  9. 支持以整数类型存储的时间字段,以兼容PHP社区的特别约定。

Statistic Process

  1. Delete invalid statistic data, e.g. data in tomorrow
  2. Count data within the specified time by the dimensions
  3. Delete overlapping data, and insert new data

FAQ

Q: Why use Sequel instead of ActiveRecord?

A: When initialize an ORM object, ActiveRecord is 3 times slower than Sequel, and we just need the basic operations, including read, write, enumerate, etc. See more details in Quick dive into Ruby ORM object initialization .

Q: Why do you recommend using multiple collections to store logs rather than a single collection, or a capped collection?

A: MongoDB can effectively reuse space freed by removing entire collections without leading to data fragmentation, see details at http://docs.mongodb.org/manual/use-cases/storing-log-data/#multiple-collections-single-database

Q: In Mongodb, why use MapReduce instead of Aggregation?

A: The result of aggregation pipeline is a document and is subject to the BSON Document size limit, which is currently 16 megabytes, see more details at http://docs.mongodb.org/manual/core/aggregation-pipeline/#pipeline

TODO

  • Admin interface
  • statistic query api in Ruby and HTTP
  • Interacting with Javascript charting library, e.g. Highcharts, D3.

Test

bundle install
bundle exec rake

Copyright

MIT. David Chen at eoe.cn, sunshine-library .