module Octo::Trends

Constants

DEFAULT_COUNT

Public Instance Methods

aggregate!(ts = Time.now.floor) click to toggle source

Override the aggregate! defined in counter class as the calculations

for trending are a little different
# 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) click to toggle source

Aggregates and creates trends for all the enterprises for a specific

trend type at a specific timestamp

@param [Fixnum] oftype The type of trend to be calculated @param [Time] ts The time at which trend needs to be calculated

# 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) click to toggle source

Performs the actual trend calculation @param [String] enterprise_id The enterprise ID for whom trend needs to be found @param [Fixnum] trend_type The trend type to be calculates @param [Time] ts The Timestamp at which trend needs to be calculated.

# 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
trend_class(klass) click to toggle source

Define the class which would be returned while fetching trending objects

# File lib/octocore-mongo/trends.rb, line 82
def trend_class(klass)
  @trend_class = klass
end
trend_for(klass) click to toggle source

Define the class for which trends shall be found

# 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() click to toggle source

Define the columns needed for Trends

# 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

Private Instance Methods

counter2trend(counter) click to toggle source

Converts a couunter into a trend @param [Object] counter A counter object. This object must belong

to one of the counter types defined in models.

@return [Object] Returns a trend instance corresponding to the counter

instance
# File lib/octocore-mongo/trends.rb, line 140
def counter2trend(counter)
  self.new({
    enterprise: counter.enterprise,
    score: score(counter.divergence),
    uid: counter.uid,
    ts: counter.ts
  })
end
score(divergence) click to toggle source

For now, just make sure divergence is absolute. This is responsible to

score a counter on the basis of its divergence

@param [Float] divergence The divergence value @return [Float] The score

# File lib/octocore-mongo/trends.rb, line 153
def score(divergence)
  return 0 if divergence.nil?
  divergence.abs
end