class MongoProfiler::Profile

Public Class Methods

register(started_at, database, collection, selector, options = {}) click to toggle source
# File lib/mongo_profiler/models/profile.rb, line 47
def register(started_at, database, collection, selector, options = {})
  return if collection =~ /mongo_profiler/ || collection =~ /system/
  return if selector['$explain']

  _caller = MongoProfiler::Caller.new(caller)

  group = ProfileGroup.find_or_create_by(name: MongoProfiler.current_group_name)

  group.touch

  profile_md5 = generate_profile_md5(database, collection, selector, _caller)

  return if Profile.where(profile_md5: profile_md5, profile_group_id: group.id).any?

  result = {}
  result[:profile_md5]        = profile_md5
  result[:profile_group_id]   = group.id

  result[:total_time]         = elapsed(started_at)
  result[:command_database]   = database
  result[:command_collection] = collection
  result[:command]            = JSON.dump(selector)
  result[:file]               = _caller.file
  result[:line]               = _caller.line
  result[:method]             = _caller.method

  # TODO do it in background
  result[:explain] = JSON.dump(generate_explain(collection, selector))

  self.create(result)
end

Private Class Methods

elapsed(started_at) click to toggle source
# File lib/mongo_profiler/models/profile.rb, line 102
def elapsed(started_at)
  (Time.now - started_at) * 1000
end
generate_explain(collection, selector) click to toggle source
# File lib/mongo_profiler/models/profile.rb, line 81
def generate_explain(collection, selector)
  query = if selector.has_key?('$query')
            selector['$query']
          else
            selector
          end
  self.collection.database[collection].find(query).explain
end
generate_profile_md5(database, collection, selector, _caller) click to toggle source
# File lib/mongo_profiler/models/profile.rb, line 90
def generate_profile_md5(database, collection, selector, _caller)
  profile_key = [
    database,
    collection,
    MongoProfiler::Util.deep_keys(selector).join,
    _caller.file,
    _caller.line.to_s
  ].join

  Digest::MD5.hexdigest(profile_key)
end

Public Instance Methods

score() click to toggle source
# File lib/mongo_profiler/models/profile.rb, line 22
def score
  explain = JSON.parse(self.explain)

  n              = explain['n']
  ns_scanned     = explain['nscanned']
  cursor         = explain['cursor']
  scan_and_order = explain['scanAndOrder']

  case
  when cursor == 'BasicCursor'
    :no_index
  when n == 0
    :no_docs_found
  when ns_scanned == n
    :perfect
  when ns_scanned > n
    :scanned_more_than_returned
  when scan_and_order
    :had_to_order
  end
rescue => e
  e.message
end