VRFS-2795 cohorts first pass
This commit is contained in:
parent
b38370589f
commit
961af94e6c
|
|
@ -1,4 +1,131 @@
|
|||
require 'date'
|
||||
|
||||
class Cohort < ActiveRecord::Base
|
||||
|
||||
KEY_SET_TOTAL = [:registered_users, :first_downloaded_client_at, :first_certified_gear_at, :music_sessions_user_history, 'play_jamtr', :jam_track_rights, :recorded_tracks, :friendships, :invited_users]
|
||||
|
||||
TOTAL_LABELS = {
|
||||
registered_users: 'Registered Users',
|
||||
first_downloaded_client_at: 'Downloaded app',
|
||||
first_certified_gear_at: 'Certified Gear',
|
||||
music_sessions_user_history: 'Played Online',
|
||||
play_jamtr: 'Played JamTrack',
|
||||
jam_track_rights: 'Purchased JamTrack',
|
||||
recorded_tracks: 'Made Recording',
|
||||
friendships: 'Connected w/Friend',
|
||||
invited_users: 'Invite Others',
|
||||
}
|
||||
|
||||
# KEY_SET_TOTAL = [:registered_users, :first_downloaded_client_at, :first_certified_gear_at, :music_session_histories, 'play_jamtr', :jam_track_rights, :recordings, :friendships, :invited_users]
|
||||
KEY_SET_MONTH = ['reg_users', :first_downloaded_client_at, :first_certified_gear_at, 'visit0-1', 'visit2-5', 'visit6+', 'play_online0-1', 'play_online2-5', 'play_online6+', 'play_jamtr0-1', 'play_jamtr2-5', 'play_jamtr6+', 'redeem_jamtr', 'purch_jamtr', 'recordings', 'friendships', 'invited_users']
|
||||
|
||||
serialize :data_set, JSON
|
||||
|
||||
before_create do
|
||||
self.data_set ||= {}
|
||||
end
|
||||
|
||||
def self.date_tuples(from,to)
|
||||
prec = from.size
|
||||
start = Date.new(*from)
|
||||
finish = Date.new(*to)
|
||||
|
||||
filter_on = [:day,:mon].first(3-prec)
|
||||
filter = ->(d) { filter_on.all? {|attr| d.send(attr) == 1 } }
|
||||
|
||||
(start..finish)
|
||||
.select(&filter)
|
||||
.map { |d| [d.year,d.mon,d.day].first(prec) }
|
||||
end
|
||||
|
||||
def self.cohort_date_ranges
|
||||
starting = User.where(admin: false).order(:created_at).first.created_at
|
||||
ending = Time.now
|
||||
dates = self.date_tuples([starting.year, starting.month],
|
||||
[ending.year, ending.month])
|
||||
ranges = []
|
||||
dates.each_with_index do |d1, idx|
|
||||
d2 = dates[idx+1] || [Time.now.next_month.year,Time.now.next_month.month]
|
||||
rr = Time.parse("#{d1[0]}-#{d1[1]}-1")..(Time.parse("#{d2[0]}-#{d2[1]}-1") - 1.second)
|
||||
ranges << rr
|
||||
end
|
||||
ranges
|
||||
end
|
||||
|
||||
def self.cumulative_cohorts
|
||||
self.cohort_date_ranges.collect do |range|
|
||||
unless cc = Cohort.where(start_date: range.first).where(cumulative: true).limit(1).first
|
||||
cc = Cohort.new
|
||||
cc.start_date = range.first
|
||||
cc.end_date = range.last
|
||||
cc.cumulative = true
|
||||
cc.save!
|
||||
end
|
||||
cc
|
||||
end
|
||||
end
|
||||
|
||||
def _join_user(assoc_ref)
|
||||
assoc_ref.active_record
|
||||
.joins("INNER JOIN users AS uu ON uu.id = #{assoc_ref.foreign_key}")
|
||||
.where(created_at: self.start_date..self.end_date)
|
||||
.where(['uu.created_at >= ? AND uu.created_at <= ?',
|
||||
self.start_date, self.end_date])
|
||||
end
|
||||
|
||||
def _put_data_set(key, count, num_user)
|
||||
self.data_set[key] = count
|
||||
self.data_set["#{key}%"] = 100.0 * (count.to_f / num_user.to_f)
|
||||
end
|
||||
|
||||
def self.user_attribute_within(attrib, cohort)
|
||||
User.where(attrib => cohort.start_date..cohort.end_date)
|
||||
end
|
||||
|
||||
def all_time!
|
||||
num_user = self.class.user_attribute_within(:created_at, self).count
|
||||
return unless 0 < num_user
|
||||
|
||||
self.data_set['registered_users'] = num_user
|
||||
num_user = num_user.to_f
|
||||
|
||||
count = self.class.user_attribute_within(:first_downloaded_client_at, self).count
|
||||
_put_data_set('first_downloaded_client_at', count, num_user)
|
||||
|
||||
count = self.class.user_attribute_within(:first_certified_gear_at, self).count
|
||||
_put_data_set('first_certified_gear_at', count, num_user)
|
||||
|
||||
count = _join_user(InvitedUser.reflections[:sender]).count
|
||||
_put_data_set('invited_users', count, num_user)
|
||||
|
||||
count = _join_user(RecordedTrack.reflections[:user]).count
|
||||
_put_data_set('recorded_tracks', count, num_user)
|
||||
|
||||
count = _join_user(Friendship.reflections[:user])
|
||||
.joins("INNER JOIN friendships AS fff ON fff.friend_id = uu.id")
|
||||
.where(['fff.created_at >= ? AND fff.created_at <= ?',
|
||||
self.start_date, self.end_date]).count
|
||||
count /= 2
|
||||
_put_data_set('friendships', count, num_user)
|
||||
|
||||
count = _join_user(JamTrackRight.reflections[:user]).count
|
||||
_put_data_set('jam_track_rights', count, num_user)
|
||||
|
||||
count = _join_user(MusicSessionUserHistory.reflections[:user]).count
|
||||
_put_data_set('music_sessions_user_history', count, num_user)
|
||||
|
||||
self.save!
|
||||
end
|
||||
|
||||
def monthly!
|
||||
count = JamTrackRight
|
||||
.where(redeemed: true)
|
||||
.where(updated_at: self.start_date..self.end_date)
|
||||
.count
|
||||
self.data_set['redeemed_jamtracks'] = count
|
||||
self.data_set["redeemed_jamtracks%"] = 100.0 * (count.to_f / num_user.to_f)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -260,4 +260,5 @@ jam_track_jmep_data.sql
|
|||
add_jam_track_bitrates.sql
|
||||
jam_track_importer.sql
|
||||
jam_track_pro_licensing_update.sql
|
||||
jam_track_redeemed.sql
|
||||
jam_track_redeemed.sql
|
||||
cohorts.sql
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
CREATE TABLE cohorts {
|
||||
CREATE TABLE cohorts (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
start_date TIMESTAMP NOT NULL,
|
||||
end_date TIMESTAMP NOT NULL,
|
||||
group_type VARCHAR(64) NOT NULL,
|
||||
cumulative BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
data_set JSON NOT NULL DEFAULT '{}',
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
};
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX index_started_date ON cohorts USING btree (start_date);
|
||||
|
|
|
|||
Loading…
Reference in New Issue