mongoid_taggable_with_context 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,71 +1,71 @@
1
- module Mongoid::TaggableWithContext::AggregationStrategy
2
- module MapReduce
3
- extend ActiveSupport::Concern
4
- included do
5
- set_callback :save, :after, :map_reduce_all_contexts!, if: :tags_changed?
6
- set_callback :destroy, :after, :map_reduce_all_contexts!
7
- delegate :aggregation_collection_for, to: "self.class"
8
- end
9
-
10
- module ClassMethods
11
- # Collection name for storing results of tag count aggregation
12
-
13
- def aggregation_database_collection_for(context)
14
- (@aggregation_database_collection ||= {})[context] ||= Moped::Collection.new(self.collection.database, aggregation_collection_for(context))
15
- end
16
-
17
- def aggregation_collection_for(context)
18
- "#{collection_name}_#{context}_aggregation"
19
- end
20
-
21
- def tags_for(context, conditions={})
22
- aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| t["_id"] }
23
- end
24
-
25
- # retrieve the list of tag with weight(count), this is useful for
26
- # creating tag clouds
27
- def tags_with_weight_for(context, conditions={})
28
- aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| [t["_id"], t["value"].to_i] }
29
- end
30
-
31
- end
32
-
33
- protected
34
-
35
- def changed_tag_arrays
36
- self.class.tag_database_fields & changes.keys.map(&:to_sym)
37
- end
38
-
39
- def tags_changed?
40
- !changed_tag_arrays.empty?
41
- end
42
-
43
- def map_reduce_all_contexts!
44
- self.class.tag_contexts.each do |context|
45
- map_reduce_context!(context)
46
- end
47
- end
48
-
49
- def map_reduce_context!(context)
50
- db_field = self.class.tag_options_for(context)[:db_field]
51
-
52
- map = <<-END
53
- function() {
54
- if (!this.#{db_field})return;
55
- for (index in this.#{db_field})
56
- emit(this.#{db_field}[index], 1);
57
- }
58
- END
59
-
60
- reduce = <<-END
61
- function(key, values) {
62
- var count = 0;
63
- for (index in values) count += values[index];
64
- return count;
65
- }
66
- END
67
-
68
- self.class.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
69
- end
70
- end
71
- end
1
+ module Mongoid::TaggableWithContext::AggregationStrategy
2
+ module MapReduce
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ set_callback :save, :after, :map_reduce_all_contexts!, if: :tags_changed?
6
+ set_callback :destroy, :after, :map_reduce_all_contexts!
7
+ delegate :aggregation_collection_for, to: "self.class"
8
+ end
9
+
10
+ module ClassMethods
11
+ # Collection name for storing results of tag count aggregation
12
+
13
+ def aggregation_database_collection_for(context)
14
+ (@aggregation_database_collection ||= {})[context] ||= Moped::Collection.new(self.collection.database, aggregation_collection_for(context))
15
+ end
16
+
17
+ def aggregation_collection_for(context)
18
+ "#{collection_name}_#{context}_aggregation"
19
+ end
20
+
21
+ def tags_for(context, conditions={})
22
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| t["_id"] }
23
+ end
24
+
25
+ # retrieve the list of tag with weight(count), this is useful for
26
+ # creating tag clouds
27
+ def tags_with_weight_for(context, conditions={})
28
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| [t["_id"], t["value"].to_i] }
29
+ end
30
+
31
+ end
32
+
33
+ protected
34
+
35
+ def changed_tag_arrays
36
+ self.class.tag_database_fields & changes.keys.map(&:to_sym)
37
+ end
38
+
39
+ def tags_changed?
40
+ !changed_tag_arrays.empty?
41
+ end
42
+
43
+ def map_reduce_all_contexts!
44
+ self.class.tag_contexts.each do |context|
45
+ map_reduce_context!(context)
46
+ end
47
+ end
48
+
49
+ def map_reduce_context!(context)
50
+ db_field = self.class.tag_options_for(context)[:db_field]
51
+
52
+ map = <<-END
53
+ function() {
54
+ if (!this.#{db_field})return;
55
+ for (index in this.#{db_field})
56
+ emit(this.#{db_field}[index], 1);
57
+ }
58
+ END
59
+
60
+ reduce = <<-END
61
+ function(key, values) {
62
+ var count = 0;
63
+ for (index in values) count += values[index];
64
+ return count;
65
+ }
66
+ END
67
+
68
+ self.class.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
69
+ end
70
+ end
71
+ end
@@ -1,116 +1,116 @@
1
- module Mongoid::TaggableWithContext::AggregationStrategy
2
- module RealTime
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- set_callback :save, :after, :update_tags_aggregations_on_save
7
- set_callback :destroy, :after, :update_tags_aggregations_on_destroy
8
- end
9
-
10
- module ClassMethods
11
- def tag_name_attribute
12
- "_id"
13
- end
14
-
15
- # Collection name for storing results of tag count aggregation
16
-
17
- def aggregation_database_collection_for(context)
18
- (@aggregation_database_collection ||= {})[context] ||= Moped::Collection.new(self.collection.database, aggregation_collection_for(context))
19
- end
20
-
21
- def aggregation_collection_for(context)
22
- "#{collection_name}_#{context}_aggregation"
23
- end
24
-
25
- def tags_for(context, conditions={})
26
- aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| t[tag_name_attribute] }
27
- end
28
-
29
- # retrieve the list of tag with weight(count), this is useful for
30
- # creating tag clouds
31
- def tags_with_weight_for(context, conditions={})
32
- aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
33
- end
34
-
35
- def recalculate_all_context_tag_weights!
36
- tag_contexts.each do |context|
37
- recalculate_tag_weights!(context)
38
- end
39
- end
40
-
41
- def recalculate_tag_weights!(context)
42
- db_field = self.class.tag_options_for(context)[:db_field]
43
-
44
- map = <<-END
45
- function() {
46
- if (!this.#{db_field})return;
47
- for (index in this.#{db_field})
48
- emit(this.#{db_field}[index], 1);
49
- }
50
- END
51
-
52
- reduce = <<-END
53
- function(key, values) {
54
- var count = 0;
55
- for (index in values) count += values[index];
56
- return count;
57
- }
58
- END
59
-
60
- self.class.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
61
- end
62
-
63
- # adapted from https://github.com/jesuisbonbon/mongoid_taggable/commit/42feddd24dedd66b2b6776f9694d1b5b8bf6903d
64
- def tags_autocomplete(context, criteria, options={})
65
- result = aggregation_database_collection_for(context).find({tag_name_attribute.to_sym => /^#{criteria}/})
66
- result = result.sort(value: -1) if options[:sort_by_count] == true
67
- result = result.limit(options[:max]) if options[:max] > 0
68
- result.to_a.map{ |r| [r[tag_name_attribute], r["value"]] }
69
- end
70
- end
71
-
72
- protected
73
-
74
- def get_conditions(context, tag)
75
- {self.class.tag_name_attribute.to_sym => tag}
76
- end
77
-
78
- def update_tags_aggregation(context, old_tags=[], new_tags=[])
79
- coll = self.class.aggregation_database_collection_for(context)
80
-
81
- old_tags ||= []
82
- new_tags ||= []
83
- unchanged_tags = old_tags & new_tags
84
- tags_removed = old_tags - unchanged_tags
85
- tags_added = new_tags - unchanged_tags
86
-
87
-
88
- tags_removed.each do |tag|
89
- coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: -1}})
90
- end
91
- tags_added.each do |tag|
92
- coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: 1}})
93
- end
94
- #coll.find({_id: {"$in" => tags_removed}}).update({'$inc' => {:value => -1}}, [:upsert])
95
- #coll.find({_id: {"$in" => tags_added}}).update({'$inc' => {:value => 1}}, [:upsert])
96
- end
97
-
98
- def update_tags_aggregations_on_save
99
- indifferent_changes = HashWithIndifferentAccess.new changes
100
- self.class.tag_database_fields.each do |field|
101
- next if indifferent_changes[field].nil?
102
-
103
- old_tags, new_tags = indifferent_changes[field]
104
- update_tags_aggregation(field, old_tags, new_tags)
105
- end
106
- end
107
-
108
- def update_tags_aggregations_on_destroy
109
- self.class.tag_database_fields.each do |field|
110
- old_tags = send field
111
- new_tags = []
112
- update_tags_aggregation(field, old_tags, new_tags)
113
- end
114
- end
115
- end
116
- end
1
+ module Mongoid::TaggableWithContext::AggregationStrategy
2
+ module RealTime
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ set_callback :save, :after, :update_tags_aggregations_on_save
7
+ set_callback :destroy, :after, :update_tags_aggregations_on_destroy
8
+ end
9
+
10
+ module ClassMethods
11
+ def tag_name_attribute
12
+ "_id"
13
+ end
14
+
15
+ # Collection name for storing results of tag count aggregation
16
+
17
+ def aggregation_database_collection_for(context)
18
+ (@aggregation_database_collection ||= {})[context] ||= Moped::Collection.new(self.collection.database, aggregation_collection_for(context))
19
+ end
20
+
21
+ def aggregation_collection_for(context)
22
+ "#{collection_name}_#{context}_aggregation"
23
+ end
24
+
25
+ def tags_for(context, conditions={})
26
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| t[tag_name_attribute] }
27
+ end
28
+
29
+ # retrieve the list of tag with weight(count), this is useful for
30
+ # creating tag clouds
31
+ def tags_with_weight_for(context, conditions={})
32
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
33
+ end
34
+
35
+ def recalculate_all_context_tag_weights!
36
+ tag_contexts.each do |context|
37
+ recalculate_tag_weights!(context)
38
+ end
39
+ end
40
+
41
+ def recalculate_tag_weights!(context)
42
+ db_field = self.class.tag_options_for(context)[:db_field]
43
+
44
+ map = <<-END
45
+ function() {
46
+ if (!this.#{db_field})return;
47
+ for (index in this.#{db_field})
48
+ emit(this.#{db_field}[index], 1);
49
+ }
50
+ END
51
+
52
+ reduce = <<-END
53
+ function(key, values) {
54
+ var count = 0;
55
+ for (index in values) count += values[index];
56
+ return count;
57
+ }
58
+ END
59
+
60
+ self.class.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
61
+ end
62
+
63
+ # adapted from https://github.com/jesuisbonbon/mongoid_taggable/commit/42feddd24dedd66b2b6776f9694d1b5b8bf6903d
64
+ def tags_autocomplete(context, criteria, options={})
65
+ result = aggregation_database_collection_for(context).find({tag_name_attribute.to_sym => /^#{criteria}/})
66
+ result = result.sort(value: -1) if options[:sort_by_count] == true
67
+ result = result.limit(options[:max]) if options[:max] > 0
68
+ result.to_a.map{ |r| [r[tag_name_attribute], r["value"]] }
69
+ end
70
+ end
71
+
72
+ protected
73
+
74
+ def get_conditions(context, tag)
75
+ {self.class.tag_name_attribute.to_sym => tag}
76
+ end
77
+
78
+ def update_tags_aggregation(context, old_tags=[], new_tags=[])
79
+ coll = self.class.aggregation_database_collection_for(context)
80
+
81
+ old_tags ||= []
82
+ new_tags ||= []
83
+ unchanged_tags = old_tags & new_tags
84
+ tags_removed = old_tags - unchanged_tags
85
+ tags_added = new_tags - unchanged_tags
86
+
87
+
88
+ tags_removed.each do |tag|
89
+ coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: -1}})
90
+ end
91
+ tags_added.each do |tag|
92
+ coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: 1}})
93
+ end
94
+ #coll.find({_id: {"$in" => tags_removed}}).update({'$inc' => {:value => -1}}, [:upsert])
95
+ #coll.find({_id: {"$in" => tags_added}}).update({'$inc' => {:value => 1}}, [:upsert])
96
+ end
97
+
98
+ def update_tags_aggregations_on_save
99
+ indifferent_changes = HashWithIndifferentAccess.new changes
100
+ self.class.tag_database_fields.each do |field|
101
+ next if indifferent_changes[field].nil?
102
+
103
+ old_tags, new_tags = indifferent_changes[field]
104
+ update_tags_aggregation(field, old_tags, new_tags)
105
+ end
106
+ end
107
+
108
+ def update_tags_aggregations_on_destroy
109
+ self.class.tag_database_fields.each do |field|
110
+ old_tags = send field
111
+ new_tags = []
112
+ update_tags_aggregation(field, old_tags, new_tags)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -1,52 +1,52 @@
1
- module Mongoid::TaggableWithContext::AggregationStrategy
2
- module RealTimeGroupBy
3
- extend ActiveSupport::Concern
4
- include Mongoid::TaggableWithContext::AggregationStrategy::RealTime
5
-
6
- module ClassMethods
7
- def tag_name_attribute
8
- "_name"
9
- end
10
-
11
- def tags_for(context, group_by, conditions={})
12
- results = if group_by
13
- query(context, group_by).to_a.map{ |t| t[tag_name_attribute] }
14
- else
15
- super(context, conditions)
16
- end
17
- results.uniq
18
- end
19
-
20
- def tags_with_weight_for(context, group_by, conditions={})
21
- results = if group_by
22
- query(context, group_by).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
23
- else
24
- super(context, conditions)
25
- end
26
-
27
- tag_hash = {}
28
- results.each do |tag, weight|
29
- tag_hash[tag] ||= 0
30
- tag_hash[tag] += weight
31
- end
32
- tag_hash.to_a
33
- end
34
-
35
- protected
36
- def query(context, group_by)
37
- aggregation_database_collection_for(context).find({value: {"$gt" => 0 }, group_by: group_by}).sort(tag_name_attribute.to_sym => 1)
38
- end
39
- end
40
-
41
- protected
42
-
43
- def get_conditions(context, tag)
44
- conditions = {self.class.tag_name_attribute.to_sym => tag}
45
- group_by = self.class.get_tag_group_by_field_for(context)
46
- if group_by
47
- conditions.merge!({group_by: self.send(group_by)})
48
- end
49
- conditions
50
- end
51
- end
1
+ module Mongoid::TaggableWithContext::AggregationStrategy
2
+ module RealTimeGroupBy
3
+ extend ActiveSupport::Concern
4
+ include Mongoid::TaggableWithContext::AggregationStrategy::RealTime
5
+
6
+ module ClassMethods
7
+ def tag_name_attribute
8
+ "_name"
9
+ end
10
+
11
+ def tags_for(context, group_by, conditions={})
12
+ results = if group_by
13
+ query(context, group_by).to_a.map{ |t| t[tag_name_attribute] }
14
+ else
15
+ super(context, conditions)
16
+ end
17
+ results.uniq
18
+ end
19
+
20
+ def tags_with_weight_for(context, group_by, conditions={})
21
+ results = if group_by
22
+ query(context, group_by).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
23
+ else
24
+ super(context, conditions)
25
+ end
26
+
27
+ tag_hash = {}
28
+ results.each do |tag, weight|
29
+ tag_hash[tag] ||= 0
30
+ tag_hash[tag] += weight
31
+ end
32
+ tag_hash.to_a
33
+ end
34
+
35
+ protected
36
+ def query(context, group_by)
37
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }, group_by: group_by}).sort(tag_name_attribute.to_sym => 1)
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def get_conditions(context, tag)
44
+ conditions = {self.class.tag_name_attribute.to_sym => tag}
45
+ group_by = self.class.get_tag_group_by_field_for(context)
46
+ if group_by
47
+ conditions.merge!({group_by: self.send(group_by)})
48
+ end
49
+ conditions
50
+ end
51
+ end
52
52
  end