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