Module: Reduceable::ClassMethods

Defined in:
lib/reduceable.rb

Instance Method Summary collapse

Instance Method Details

#build(collection, map, reduce, query = {}) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/reduceable.rb', line 90

def build(collection, map, reduce, query = {})
  if requires_mr_update collection
    mr_status = MrStatus.new
    mr_status.collection_name = collection
    mr_status.status = false
    mr_status.base_class = self.to_s
    mr_status.save
    opts = {:out => {:replace => collection}, :query => query}
    self.collection.map_reduce(map, reduce, opts)
  else
    self.database[collection]
  end
end

#count_by(index, query = {}) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/reduceable.rb', line 51

def count_by(index, query={})
  collection = mr_collection_name("count_by_#{index}", query) 
  map = count_map(index)
  reduce = count_reduce
  
  return build(collection, map, reduce, query).find
end

#count_map(key) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/reduceable.rb', line 58

def count_map(key)
  # Not sure how to handle hashes yet
  key = key.to_s if key.is_a? Symbol
  if self.keys[key].type == Array
    "function(){this.#{key}.forEach(function(value){emit(value, 1);});}"
  else
    "function(){emit(this.#{key}, 1);}"
  end
end

#count_reduceObject



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/reduceable.rb', line 67

def count_reduce
  <<-REDUCE
    function(key, values) {
      var total = 0;
      for (var i=0; i<values.length; i++){
        total += values[i];
      }
      return total;
    }
  REDUCE
end

#mr_collection_name(action, query = {}) ⇒ Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/reduceable.rb', line 79

def mr_collection_name(action, query = {})
  # we need a unique collection name based off the query
  # this introduces a fun bug where if your query params are in a random order
  # you won't get the performance increase of reusing map/reduce collections
  # TODO: come up with a better way of getting the collection name
  name_encoded = UUIDTools::UUID.md5_create(UUIDTools::UUID_DNS_NAMESPACE, action + query.to_s).to_s
  name = (self.to_s.downcase + name_encoded)
  puts "Name: #{name}"
  return name
end

#requires_mr_update(collection) ⇒ Object

Does this particular map reduce require an update?



105
106
107
108
109
110
111
# File 'lib/reduceable.rb', line 105

def requires_mr_update(collection)
  status_list = MrStatus.where(:collection_name => collection).all
  return true if status_list.count == 0
  status_list.each do |status|
    return status.status
  end
end

#sum_map(property, index) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/reduceable.rb', line 31

def sum_map(property, index)
  index = index.to_s if index.is_a? Symbol
  if self.keys[index].type == Array
    "function(){var amount = this.#{property};this.#{index}.forEach(function(value){emit(value, amount);});}"
  else
    "function(){emit(this.#{index}, this.#{property});}"
  end
end

#sum_of(property, index, query = {}) ⇒ Object



25
26
27
28
29
30
# File 'lib/reduceable.rb', line 25

def sum_of(property, index, query={})
  collection = mr_collection_name("sum_of_#{property}_by_#{index}", query) 
  map = sum_map(property, index)
  reduce = sum_reduce
  return build(collection, map, reduce, query).find
end

#sum_reduceObject



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/reduceable.rb', line 39

def sum_reduce 
  <<-REDUCE
    function(key, values) {
      var total = 0;
      for (var i=0; i<values.length; i++){
        total += values[i];
      }
      return total;
    }
  REDUCE
end