app/models/cohortly/metric.rb in cohortly-0.0.5 vs app/models/cohortly/metric.rb in cohortly-0.0.6

- old
+ new

@@ -8,11 +8,11 @@ key :username, String key :tags, Array key :controller, String key :action, String timestamps! - + ensure_index :tags def self.store!(args) data = args[4] data[:tags] = [] @@ -22,25 +22,66 @@ end data[:user_email] = data[:email] if data[:email] data[:tags] += data[:add_tags] if data[:add_tags] create(data) end - - def self.cohort_chart_for_tag(tags = nil) - query = {} - query = { :tags => { :$all => tags } } if tags - self.collection.map_reduce(self.month_map, + + def self.cohort_chart(tags = nil, groups = nil, weekly = false) + query = { } + query = {:tags => { :$in => tags} } if tags + if groups + query[:$where] = "function() { return #{ groups.collect {|x| 'this.tags.indexOf("' + x + '") >= 0' }.join(' || ') }; }" + end + collection_name = self.report_table_name(tags, groups, weekly) + # incremental map_reduce pattern + meta = Cohortly::ReportMeta.find_or_create_by_collection_name(collection_name) + query[:created_at] = { :$gt => meta.last_update_on.utc } if meta.last_update_on + self.collection.map_reduce(weekly ? self.week_map : self.month_map, self.reduce, - { :out => self.report_table_name(tags), + { :out => meta.last_update_on ? { :reduce => collection_name } : collection_name, :raw => true, - :query => query}) + :query => query}) + meta.last_update_on = Time.now.utc + meta.save end - - def self.report_table_name(tags = nil) - "cohort_report#{ tags ? "_#{ tags.sort.join('_') }" : '' }_#{ Time.now.strftime("%m-%d-%Y") }" + + def self.cohort_chart_for_tag(tags = nil, groups = nil) + self.cohort_chart(tags, groups, false) end + def self.weekly_cohort_chart_for_tag(tags = nil, groups = nil) + self.cohort_chart(tags, groups, true) + end + + def self.report_table_name(tags = nil, groups = nil, weekly = true) + "cohortly_report#{ tags ? "-tags=#{ tags.sort.join(':') }" : '' }#{ groups ? "-groups=#{ groups.sort.join(':') }" : '' }#{ weekly ? '-weekly' : '-monthly'}" + end + + def self.report_name_to_args(name) + name = name.gsub(/^cohortly_report/, '') + if name =~ /-weekly$/ + weekly = true + name = name.gsub(/-weekly$/, '') + else + weekly = false + name = name.gsub(/-monthly$/, '') + end + tags = nil + groups = nil + if name.length > 0 + name = name.gsub(/-tags/, 'tags') + tags, groups = name.split('-') + tags = tags.gsub(/tags=/, '').split(':') + tags = tags.any? ? tags : nil + if groups + groups = groups.gsub(/groups=/,'').split(':') + groups = groups.any? ? groups : nil + end + end + [tags, groups, weekly] + end + def self.month_map <<-JS function() { function get_month_date(date) { var year = date.getYear() + 1900; @@ -56,10 +97,23 @@ emit( start_date, payload ); } JS end + def self.week_map + <<-JS + function() { + var start_date = week_key(this.user_start_date); + var happened_on = week_key(this.created_at); + var payload = {}; + payload[happened_on] = {}; + payload[happened_on][this.user_id] = 1; + emit( start_date, payload ); + } + JS + end + def self.reduce <<-JS function(key, values) { var result = {}; values.forEach(function(value) { @@ -75,8 +129,7 @@ }); return result; } JS end - end end