Class: Vanity::Adapters::MongodbAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/vanity/adapters/mongodb_adapter.rb

Overview

MongoDB adapter.

Since:

  • 1.4.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ MongodbAdapter

Returns a new instance of MongodbAdapter

Since:

  • 1.4.0



20
21
22
23
24
25
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 20

def initialize(options)
  setup_connection(options)
  @options = options.clone
  @options[:database] ||= (@options[:path] && @options[:path].split("/")[1]) || "vanity"
  connect!
end

Instance Attribute Details

#mongoObject (readonly)

Since:

  • 1.4.0



18
19
20
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 18

def mongo
  @mongo
end

Instance Method Details

#ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false) ⇒ Object

Since:

  • 1.4.0



169
170
171
172
173
174
175
176
177
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 169

def ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false)
  if implicit
    @participants.update({ :experiment=>experiment, :identity=>identity }, { "$push"=>{ :seen=>alternative } }, :upsert=>true)
  else
    participating = @participants.find_one(:experiment=>experiment, :identity=>identity, :seen=>alternative)
  end
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$push"=>{ :converted=>alternative } }, :upsert=>true) if implicit || participating
  @experiments.update({ :_id=>experiment }, { "$inc"=>{ "conversions.#{alternative}"=>count } }, :upsert=>true)
end

#ab_add_participant(experiment, alternative, identity) ⇒ Object

Since:

  • 1.4.0



153
154
155
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 153

def ab_add_participant(experiment, alternative, identity)
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$push"=>{ :seen=>alternative } }, :upsert=>true)
end

#ab_assigned(experiment, identity) ⇒ Object

Returns the participant's seen alternative in this experiment, if it exists

Since:

  • 1.4.0



164
165
166
167
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 164

def ab_assigned(experiment, identity)
  participant = @participants.find_one({ :experiment=>experiment, :identity=>identity }, { :fields=>[:seen] })
  participant && participant["seen"].first
end

#ab_counts(experiment, alternative) ⇒ Object

Since:

  • 1.4.0



132
133
134
135
136
137
138
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 132

def ab_counts(experiment, alternative)
  record = @experiments.find_one({ :_id=>experiment }, { :fields=>[:conversions] })
  conversions = record && record["conversions"]
  { :participants => @participants.find({ :experiment=>experiment, :seen=>alternative }).count,
    :converted    => @participants.find({ :experiment=>experiment, :converted=>alternative }).count,
    :conversions  => conversions && conversions[alternative.to_s] || 0 }
end

#ab_get_outcome(experiment) ⇒ Object

Since:

  • 1.4.0



179
180
181
182
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 179

def ab_get_outcome(experiment)
  experiment = @experiments.find_one({ :_id=>experiment }, { :fields=>[:outcome] })
  experiment && experiment["outcome"]
end

#ab_not_showing(experiment, identity) ⇒ Object

Since:

  • 1.4.0



149
150
151
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 149

def ab_not_showing(experiment, identity)
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$unset"=>:show })
end

#ab_seen(experiment, identity, alternative) ⇒ Object

Determines if a participant already has seen this alternative in this experiment.

Since:

  • 1.4.0



158
159
160
161
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 158

def ab_seen(experiment, identity, alternative)
  participant = @participants.find_one({ :experiment=>experiment, :identity=>identity }, { :fields=>[:seen] })
  participant && participant["seen"].first == alternative.id
end

#ab_set_outcome(experiment, alternative = 0) ⇒ Object

Since:

  • 1.4.0



184
185
186
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 184

def ab_set_outcome(experiment, alternative = 0)
  @experiments.update({ :_id=>experiment }, { "$set"=>{ :outcome=>alternative } }, :upsert=>true)
end

#ab_show(experiment, identity, alternative) ⇒ Object

Since:

  • 1.4.0



140
141
142
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 140

def ab_show(experiment, identity, alternative)
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$set"=>{ :show=>alternative } }, :upsert=>true)
end

#ab_showing(experiment, identity) ⇒ Object

Since:

  • 1.4.0



144
145
146
147
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 144

def ab_showing(experiment, identity)
  participant = @participants.find_one({ :experiment=>experiment, :identity=>identity }, { :fields=>[:show] })
  participant && participant["show"]
end

#active?Boolean

Since:

  • 1.4.0



37
38
39
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 37

def active?
  @mongo.connected?
end

#connect!Object

Since:

  • 1.4.0



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 52

def connect!
  @mongo ||= setup_connection(@options)
  @mongo.connect
  database = @mongo.db(@options[:database])
  database.authenticate @options[:username], @options[:password], true if @options[:username]
  @metrics = database.collection("vanity.metrics")
  @experiments = database.collection("vanity.experiments")
  @participants = database.collection("vanity.participants")
  @participants.create_index [[:experiment, 1], [:identity, 1]], :unique=>true
  @participants.create_index [[:experiment, 1], [:seen, 1]]
  @participants.create_index [[:experiment, 1], [:converted, 1]]
  @mongo
end

#destroy_experiment(experiment) ⇒ Object

Since:

  • 1.4.0



188
189
190
191
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 188

def destroy_experiment(experiment)
  @experiments.remove :_id=>experiment
  @participants.remove :experiment=>experiment
end

#destroy_metric(metric) ⇒ Object

Since:

  • 1.4.0



99
100
101
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 99

def destroy_metric(metric)
  @metrics.remove :_id=>metric
end

#disconnect!Object

Since:

  • 1.4.0



41
42
43
44
45
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 41

def disconnect!
  @mongo.close rescue nil if @mongo
  @metrics, @experiments = nil
  @mongo = nil
end

#experiment_persisted?(experiment) ⇒ Boolean

– Experiments –

Since:

  • 1.4.0



106
107
108
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 106

def experiment_persisted?(experiment)
  !!@experiments.find_one({ :_id=>experiment })
end

#flushdbObject

Since:

  • 1.4.0



71
72
73
74
75
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 71

def flushdb
  @metrics.drop
  @experiments.drop
  @participants.drop
end

#get_experiment_completed_at(experiment) ⇒ Object

Since:

  • 1.4.0



123
124
125
126
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 123

def get_experiment_completed_at(experiment)
  record = @experiments.find_one({ :_id=>experiment }, { :fields=>[:completed_at] })
  record && record["completed_at"]
end

#get_experiment_created_at(experiment) ⇒ Object

Since:

  • 1.4.0



114
115
116
117
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 114

def get_experiment_created_at(experiment)
  record = @experiments.find_one({ :_id=>experiment }, { :fields=>[:created_at] })
  record && record["created_at"]
end

#get_metric_last_update_at(metric) ⇒ Object

– Metrics –

Since:

  • 1.4.0



80
81
82
83
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 80

def get_metric_last_update_at(metric)
  record = @metrics.find_one(:_id=>metric)
  record && record["last_update_at"]
end

#is_experiment_completed?(experiment) ⇒ Boolean

Since:

  • 1.4.0



128
129
130
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 128

def is_experiment_completed?(experiment)
  !!@experiments.find_one(:_id=>experiment, :completed_at=>{ "$exists"=>true })
end

#metric_track(metric, timestamp, identity, values) ⇒ Object

Since:

  • 1.4.0



85
86
87
88
89
90
91
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 85

def metric_track(metric, timestamp, identity, values)
  inc = {}
  values.each_with_index do |v,i|
    inc["data.#{timestamp.to_date}.#{i}"] = v
  end
  @metrics.update({ :_id=>metric }, { "$inc"=>inc, "$set"=>{ :last_update_at=>Time.now } }, :upsert=>true)
end

#metric_values(metric, from, to) ⇒ Object

Since:

  • 1.4.0



93
94
95
96
97
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 93

def metric_values(metric, from, to)
  record = @metrics.find_one(:_id=>metric)
  data = record && record["data"] || {}
  (from.to_date..to.to_date).map { |date| (data[date.to_s] || {}).values }
end

#reconnect!Object

Since:

  • 1.4.0



47
48
49
50
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 47

def reconnect!
  disconnect!
  connect!
end

#set_experiment_completed_at(experiment, time) ⇒ Object

Since:

  • 1.4.0



119
120
121
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 119

def set_experiment_completed_at(experiment, time)
  @experiments.update({ :_id=>experiment }, { "$set"=>{ :completed_at=>time } }, :upsert=>true)
end

#set_experiment_created_at(experiment, time) ⇒ Object

Since:

  • 1.4.0



110
111
112
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 110

def set_experiment_created_at(experiment, time)
  @experiments.insert(:_id=>experiment, :created_at=>time)
end

#setup_connection(options = {}) ⇒ Object

Since:

  • 1.4.0



27
28
29
30
31
32
33
34
35
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 27

def setup_connection(options = {})
  if options[:hosts]
    args = (options[:hosts].map{|host| [host, options[:port]] } << {:connect => false})
    @mongo = Mongo::ReplSetConnection.new(*args)
  else
    @mongo = Mongo::Connection.new(options[:host], options[:port], :connect => false)
  end
  @mongo
end

#to_sObject

Since:

  • 1.4.0



66
67
68
69
# File 'lib/vanity/adapters/mongodb_adapter.rb', line 66

def to_s
  userinfo = @options.values_at(:username, :password).join(":") if @options[:username]
  URI::Generic.build(:scheme=>"mongodb", :userinfo=>userinfo, :host=>(@mongo.host || @options[:host]), :port=>(@mongo.port || @options[:port]), :path=>"/#{@options[:database]}").to_s
end