Class: AwesomeExplain::Renderers::Mongoid

Inherits:
Object
  • Object
show all
Defined in:
lib/awesome_explain/renderers/mongoid.rb

Constant Summary collapse

COLOR_ESCAPES =
{
  none: 0, bright: 1, black: 30,
  red: 31, green: 32, yellow: 33,
  blue: 34, magenta: 35, cyan: 36,
  white: 37, default: 39
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query) ⇒ Mongoid



13
14
15
# File 'lib/awesome_explain/renderers/mongoid.rb', line 13

def initialize(query)
  @query = query
end

Instance Attribute Details

#queryObject (readonly)

Returns the value of attribute query.



4
5
6
# File 'lib/awesome_explain/renderers/mongoid.rb', line 4

def query
  @query
end

#resultObject (readonly)

Returns the value of attribute result.



4
5
6
# File 'lib/awesome_explain/renderers/mongoid.rb', line 4

def result
  @result
end

Instance Method Details

#bg_color(clr, text = nil) ⇒ Object

Text background color



29
30
31
# File 'lib/awesome_explain/renderers/mongoid.rb', line 29

def bg_color(clr, text = nil)
  "\x1B[" + ((COLOR_ESCAPES[clr] || 0) + 10).to_s + 'm' + (text ?  text + "\x1B[0m" : '')
end

#dig_input_stages(stage, str, used_indexes, input_stages = false) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/awesome_explain/renderers/mongoid.rb', line 101

def dig_input_stages(stage, str, used_indexes, input_stages = false)
  used_indexes << "#{stage.dig('indexName')} (#{stage.dig('direction')})" if stage.dig('indexName').present?
  if stage.dig('inputStage').nil? && stage.dig('inputStages').nil?
    str += ' -> ' + stage_label_and_stats(stage)
  end
  if stage.dig('inputStage').present?
    str += ' ->' if !input_stages
    str += ' ' + stage_label_and_stats(stage)
    str = dig_input_stages(stage.dig('inputStage'), str, used_indexes, input_stages)
  end

  if stage.dig('inputStages').present?
    str += ' -> ' + stage_label_and_stats(stage) + ' ->'
    str += ' [ '
    stage.dig('inputStages').each_with_index do |s, idx|
      str = dig_input_stages(s, str, used_indexes, true)
      str += ' , ' if idx < stage.dig('inputStages').size - 1
    end
    str += ' ] '
  end

  str
end

#execution_statsObject



97
98
99
# File 'lib/awesome_explain/renderers/mongoid.rb', line 97

def execution_stats
  root.dig('executionStats')
end

#fg_color(clr, text = nil) ⇒ Object

Text foreground color



24
25
26
# File 'lib/awesome_explain/renderers/mongoid.rb', line 24

def fg_color(clr, text = nil)
  "\x1B[" + (COLOR_ESCAPES[clr] || 0).to_s + 'm' + (text ? text + "\x1B[0m" : '')
end


17
18
19
20
21
# File 'lib/awesome_explain/renderers/mongoid.rb', line 17

def print
  @result = query.explain

  print_general_info
end


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/awesome_explain/renderers/mongoid.rb', line 33

def print_general_info
  ap result, indent: -2
  table = Terminal::Table.new do |t|
    winning_plan_label = 'Winning Plan'
    plan_data = winning_plan_data
    winning_plan_str = plan_data[0]
    used_indexes = plan_data[1]
    winning_plan_label = fg_color :red, winning_plan_label if winning_plan_str =~ /COLLSCAN/
    t << [winning_plan_label, winning_plan_str]
    t << :separator
    t << ['Used Indexes', used_indexes.join(', ')]
    if execution_stats
      t << :separator
      t << ['Rejected Plans', rejected_plans.size]
      t << :separator
      t << ['Documents Returned', execution_stats.dig('nReturned')]
      t << :separator
      t << ['Documents Examined', execution_stats.dig('totalDocsExamined')]
      t << :separator
      t << ['Keys Examined', execution_stats.dig('totalKeysExamined')]
      t << :separator

      # Execution Time
      exec_time = execution_stats.dig('executionTimeMillis').to_f/1000
      exec_time_ms = execution_stats.dig('executionTimeMillis')
      exec_label = 'Execution time(s)'
      exec_label_ms = 'Execution time(ms)'

      if exec_time > 10
        exec_label = fg_color :red, exec_label
        exec_label_ms = fg_color :red, exec_label_ms
      end
      t << [exec_label_ms, exec_time_ms]
      t << :separator
      t << [exec_label, exec_time]
    end
  end

  puts
  puts table
  puts
end

#rejected_plansObject



93
94
95
# File 'lib/awesome_explain/renderers/mongoid.rb', line 93

def rejected_plans
  root.dig('queryPlanner', 'rejectedPlans')
end

#rootObject



85
86
87
# File 'lib/awesome_explain/renderers/mongoid.rb', line 85

def root
  result.dig('$cursor') || result
end

#stage_label_and_stats(stage) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/awesome_explain/renderers/mongoid.rb', line 125

def stage_label_and_stats(stage)
  str = "#{stage.dig('stage')} ("
  str += "#{stage.dig('docsExamined')} / " if stage.dig('docsExamined').present?
  str += stage.dig('nReturned').to_s if stage.dig('nReturned').present?
  str += ')'

  str.gsub(' ()', '')
end

#winning_planObject



89
90
91
# File 'lib/awesome_explain/renderers/mongoid.rb', line 89

def winning_plan
  root.dig('executionStats', 'executionStages') || root.dig('queryPlanner', 'winningPlan')
end

#winning_plan_dataObject



76
77
78
79
80
81
82
83
# File 'lib/awesome_explain/renderers/mongoid.rb', line 76

def winning_plan_data
  used_indexes = []
  plan = winning_plan
  plan_str = stage_label_and_stats(plan)
  plan_str = dig_input_stages(plan.dig('inputStage'), plan_str, used_indexes) if plan['inputStage']

  [plan_str, used_indexes]
end