Module: Octo::Trends
- Includes:
- Counter::Helper
- Included in:
- CategoryTrend, ProductTrend, TagTrend
- Defined in:
- lib/octocore-mongo/trends.rb
Constant Summary collapse
- DEFAULT_COUNT =
10
Constants included from Counter::Helper
Counter::Helper::METHOD_PREFIX
Instance Method Summary collapse
-
#aggregate!(ts = Time.now.floor) ⇒ Object
Override the aggregate! defined in counter class as the calculations for trending are a little different.
-
#aggregate_and_create(oftype, ts = Time.now.floor) ⇒ Object
Aggregates and creates trends for all the enterprises for a specific trend type at a specific timestamp.
-
#calculate(enterprise_id, trend_type, ts = Time.now.floor) ⇒ Object
Performs the actual trend calculation.
-
#get_trending(enterprise_id, type, opts = {}) ⇒ Object
Gets the trend of a type at a time.
-
#trend_class(klass) ⇒ Object
Define the class which would be returned while fetching trending objects.
-
#trend_for(klass) ⇒ Object
Define the class for which trends shall be found.
-
#trendable ⇒ Object
Define the columns needed for Trends.
Methods included from Counter::Helper
counter_text, #generate_aggregators, #get_duration_for_counter_type, #get_fromtype_for_totype, #get_typecounters, #max_type, #method_names_type_counter, #string_to_const_val, #type_counters_method_names
Instance Method Details
#aggregate!(ts = Time.now.floor) ⇒ Object
Override the aggregate! defined in counter class as the calculations
for trending are a little different
40 41 42 |
# File 'lib/octocore-mongo/trends.rb', line 40 def aggregate!(ts = Time.now.floor) aggregate_and_create(Octo::Counter::TYPE_MINUTE, ts) end |
#aggregate_and_create(oftype, ts = Time.now.floor) ⇒ Object
Aggregates and creates trends for all the enterprises for a specific
trend type at a specific
32 33 34 35 36 |
# File 'lib/octocore-mongo/trends.rb', line 32 def aggregate_and_create(oftype, ts = Time.now.floor) Octo::Enterprise.each do |enterprise| calculate(enterprise.id, oftype, ts) end end |
#calculate(enterprise_id, trend_type, ts = Time.now.floor) ⇒ Object
Performs the actual trend calculation
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/octocore-mongo/trends.rb', line 48 def calculate(enterprise_id, trend_type, ts = Time.now.floor) args = { enterprise_id: enterprise_id, ts: ts, type: trend_type } klass = @trend_for.constantize hitsResult = klass.public_send(:where, args) trends = hitsResult.map { |h| counter2trend(h) } # group trends as per the time of their happening and rank them on their # score grouped_trends = trends.group_by { |x| x.ts } grouped_trends.each do |_ts, trendlist| sorted_trendlist = trendlist.sort_by { |x| x.score } sorted_trendlist.each_with_index do |trend, index| trend.rank = index trend.type = trend_type trend.save! end end end |
#get_trending(enterprise_id, type, opts = {}) ⇒ Object
Gets the trend of a type at a time
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/octocore-mongo/trends.rb', line 90 def get_trending(enterprise_id, type, opts={}) ts = opts.fetch(:ts, Time.now.floor) args = { enterprise_id: enterprise_id, ts: opts.fetch(:ts, Time.now.floor), type: type } res = where(args).limit(opts.fetch(:limit, DEFAULT_COUNT)) enterprise = Octo::Enterprise.find_by_id(enterprise_id) if res.count == 0 and enterprise.fakedata? Octo.logger.info 'Beginning to fake data' res = [] if ts.class == Range ts_begin = ts.begin ts_end = ts.end ts_begin.to(ts_end, 1.day).each do |_ts| 3.times do |rank| items = @trend_class.constantize.send(:where, {enterprise_id: enterprise_id}).first(10) if items.count > 0 uid = items.shuffle.pop.unique_id _args = args.merge( ts: _ts, rank: rank, score: rank+1, uid: uid ) res << self.new(_args).save! end end end elsif ts.class == Time 3.times do |rank| uid = 0 items = @trend_class.constantize.send(:where, {enterprise_id: enterprise_id}).first(10) if items.count > 0 uid = items.shuffle.pop.unique_id _args = args.merge( rank: rank, score: rank+1, uid: uid ) res << self.new(_args).save! end end end end res.map do |r| clazz = @trend_class.constantize clazz.public_send(:recreate_from, r) end end |
#trend_class(klass) ⇒ Object
Define the class which would be returned while fetching trending objects
82 83 84 |
# File 'lib/octocore-mongo/trends.rb', line 82 def trend_class(klass) @trend_class = klass end |
#trend_for(klass) ⇒ Object
Define the class for which trends shall be found
73 74 75 76 77 78 79 |
# File 'lib/octocore-mongo/trends.rb', line 73 def trend_for(klass) unless klass.constantize.ancestors.include?MongoMapper::Document raise ArgumentError, "Class #{ klass } does not represent a DB Model" else @trend_for = klass end end |
#trendable ⇒ Object
Define the columns needed for Trends
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/octocore-mongo/trends.rb', line 13 def trendable key :type, Integer key :ts, Time key :rank, Integer key :score, Float key :uid, String generate_aggregators { |ts, method| trendtype = method_names_type_counter(method) aggregate_and_create trendtype, ts } end |