rugroupy 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7b69371b6c1ce1614240f1004dec002198a2bdce
4
+ data.tar.gz: 445979aee0419c7afd6b75c15f85c70dd64613a4
5
+ SHA512:
6
+ metadata.gz: 11db4f7986672bbe6593e684545bb1062fb221b3b8a31ce113aef3ae11b437b943ddfce638884c4df05c0461ef2a297a5849fc1bc7baeab2c0a3c12c8278853b
7
+ data.tar.gz: 74d42da682eb28216a8c19f8fad109bfdf6479ef8639cf35ce570277c5be4c87d10a0aa351a9499d0ccfa167ddf8881653fca11ce87e8f132fba5d2d9b712e82
data/README.rdoc CHANGED
@@ -25,6 +25,15 @@ See http://github.com/rwynn/rugroupy/tree/master/test
25
25
 
26
26
  * sudo gem install rugroupy
27
27
 
28
+ == Install from the GitHub source
29
+
30
+ The source code is available at http://github.com/rwynn/rugroupy.
31
+ You can either clone the git repository or download a tarball or zip file.
32
+ Once you have the source, you can use it from wherever you downloaded it or
33
+ you can install it as a gem from the source by typing
34
+
35
+ * sudo rake install
36
+
28
37
  == Contributing to rugroupy
29
38
 
30
39
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
data/lib/rugroupy.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  require 'rugroupy/entity'
2
- require 'rugroupy/group'
2
+ require 'rugroupy/group'
@@ -2,85 +2,89 @@ require 'mongo'
2
2
  require 'bson'
3
3
 
4
4
  module Groupy
5
-
6
5
  class Entity
7
- def initialize(database, name, entity_id, create=true)
8
- @database, @name, @entity_id = database, name, entity_id
9
- @database.create_collection(@name) if not @database.collection_names.member?(@name)
10
-
11
- @database["#{@name}_count"].ensure_index([['_id.e', Mongo::DESCENDING],
12
- ['_id.tag', Mongo::DESCENDING],
13
- ['value.count', Mongo::DESCENDING]], :background => false)
14
-
6
+ def initialize(database, name, entity_id, create = true)
7
+ @database = database
8
+ @name = name
9
+ @entity_id = entity_id
10
+ @database[@name].create unless @database.collection_names.member?(@name)
11
+
12
+ @database["#{@name}_count"].indexes.create_many([
13
+ { key: { '_id.e' => -1 }, background: false },
14
+ { key: { '_id.tag' => -1 }, background: false },
15
+ { key: { 'value.count' => -1 }, background: false }
16
+ ])
17
+
15
18
  if create
16
19
  begin
17
- doc = Hash["_id"=>@entity_id, "tags"=>Hash.new]
18
- @database[@name].insert(doc, :safe=>true)
19
- rescue Mongo::MongoDBError => e
20
+ doc = Hash['_id' => @entity_id, 'tags' => {}]
21
+ @database[@name].insert_one(doc, safe: true)
22
+ rescue Mongo::Error => e
20
23
  end
21
24
  end
22
25
  end
23
26
 
24
27
  def get
25
- @database[@name].find_one({ "_id" => @entity_id })
28
+ @database[@name].find('_id' => @entity_id).first
26
29
  end
27
-
30
+
28
31
  def delete
29
- @database[@name].remove({"_id" => @entity_id}, :safe => true)
32
+ @database[@name].delete_one({ '_id' => @entity_id }, safe: true)
30
33
  nil
31
34
  end
32
35
 
33
36
  def clear_tags
34
- spec = {"_id" => @entity_id }
35
- doc = {"$set" => { "tags" => Hash.new } }
36
- @database[@name].update(spec, doc, :safe=>true)
37
+ spec = { '_id' => @entity_id }
38
+ doc = { '$set' => { 'tags' => {} } }
39
+ @database[@name].update_one(spec, doc, safe: true)
37
40
  nil
38
41
  end
39
-
42
+
40
43
  def has_tag(tag, value)
41
- e = self.get()
42
- e['tags'].member?(tag) and e['tags'][tag].member?(value)
44
+ e = get
45
+ e['tags'].member?(tag) && e['tags'][tag].member?(value)
43
46
  end
44
-
47
+
45
48
  def tag(tag, value)
46
- self.apply_tag(tag, value)
49
+ apply_tag(tag, value)
47
50
  nil
48
51
  end
49
-
52
+
50
53
  def untag(tag, value)
51
- self.apply_tag(tag, value, add=false)
54
+ apply_tag(tag, value, add = false)
52
55
  nil
53
56
  end
54
-
55
- def apply_tag(tag, value, add=true)
56
- op = add ? "$addToSet" : "$pull"
57
- doc = Hash.new
57
+
58
+ def apply_tag(tag, value, add = true)
59
+ op = add ? '$addToSet' : '$pull'
60
+ doc = {}
58
61
  field = "tags.#{tag}"
59
- unless value.is_a?(Array)
60
- doc[op] = { field => value }
62
+ if value.is_a?(Array)
63
+ op = '$pullAll' unless add
64
+ doc[op] = add ? { field => { '$each' => value } } : { field => value }
61
65
  else
62
- op = "$pullAll" unless add
63
- doc[op] = add ? {field => {"$each" => value}} : {field => value}
66
+ doc[op] = { field => value }
64
67
  end
65
- spec = Hash["_id" => @entity_id]
66
- @database[@name].update(spec, doc, :safe=>true)
68
+ spec = Hash['_id' => @entity_id]
69
+ @database[@name].update_one(spec, doc, safe: true)
67
70
  nil
68
71
  end
69
-
70
- def similiar(tag=nil, skip=nil, limit=nil, reverse=false)
71
- q = BSON::OrderedHash.new
72
- q["_id.e"] = @entity_id
73
- q["_id.tag"] = tag ? tag : {"$exists" => false}
74
- cursor = @database["#{@name}_count"].find(q, :fields => {"_id.e" => 1})
75
- cursor.skip(skip) if skip
76
- cursor.limit(limit) if limit
77
- cursor.sort("value.count", reverse ? Mongo::ASCENDING : Mongo::DESCENDING)
72
+
73
+ def similiar(tag = nil, skip = nil, limit = nil, reverse = false)
74
+ q = BSON::Document.new
75
+ q['_id.e'] = @entity_id
76
+ q['_id.tag'] = tag ? tag : { '$exists' => false }
77
+ opts = {
78
+ projection: { '_id.e' => 1 },
79
+ sort: { 'value.count' => reverse ? 1 : -1 }
80
+ }
81
+ opts[:skip] = skip if skip
82
+ opts[:limit] = limit if limit
83
+ cursor = @database["#{@name}_count"].find(q, opts)
78
84
  cursor.collect do |r|
79
- pair = r["_id"]["e"]
85
+ pair = r['_id']['e']
80
86
  pair[0] == @entity_id ? pair[1] : pair[0]
81
87
  end
82
88
  end
83
-
84
89
  end
85
90
  end
86
-
@@ -2,100 +2,102 @@ require 'mongo'
2
2
  require 'bson'
3
3
 
4
4
  module Groupy
5
-
6
5
  class EntityGrouper
7
-
8
- @@defaultScoreFunction = "function(tag) { return 1; }"
9
- @@defaultIncludeFunction = "function(tag) { return true; }"
10
- @@dynamicTagFunction = "function(doc) {}"
11
-
6
+ @@defaultScoreFunction = 'function(tag) { return 1; }'
7
+ @@defaultIncludeFunction = 'function(tag) { return true; }'
8
+ @@dynamicTagFunction = 'function(doc) {}'
9
+
12
10
  def initialize(database, entity)
13
- @database, @entity = database, entity
14
- @database["#{@entity}_count"].ensure_index([['_id.tag', Mongo::DESCENDING],
15
- ['value.count', Mongo::DESCENDING]], :background => false)
11
+ @database = database
12
+ @entity = entity
13
+ @database["#{@entity}_count"].indexes.create_many([
14
+ { key: { '_id.tag' => -1 }, background: false },
15
+ { key: { 'value.count' => -1 }, background: false }
16
+ ])
16
17
  end
17
-
18
- def similiar(tag=nil, skip=nil, limit=nil, reverse=false)
19
- q = BSON::OrderedHash.new
20
- q["_id.tag"] = tag ? tag : {"$exists" => false}
21
- cursor = @database["#{@entity}_count"].find(q, :fields => {"_id.e" => 1})
22
- cursor.skip(skip) if skip
23
- cursor.limit(limit) if limit
24
- cursor.sort("value.count", reverse ? Mongo::ASCENDING : Mongo::DESCENDING)
25
- cursor.collect { |r| r["_id"]["e"] }
18
+
19
+ def similiar(tag = nil, skip = nil, limit = nil, reverse = false)
20
+ q = BSON::Document.new
21
+ q['_id.tag'] = tag ? tag : { '$exists' => false }
22
+ opts = {
23
+ projection: { '_id.e' => 1 },
24
+ sort: { 'value.count' => reverse ? 1 : -1 }
25
+ }
26
+ opts[:skip] = skip if skip
27
+ opts[:limit] = limit if limit
28
+ cursor = @database["#{@entity}_count"].find(q, opts)
29
+ cursor.collect { |r| r['_id']['e'] }
26
30
  end
27
-
28
- def group(options={})
29
- self.invert_entities(options[:includeFunction] || @@defaultIncludeFunction,
30
- options[:dynamicTagFunction] || @@dynamicTagFunction)
31
- self.count_entities(options[:scoreFunction] || @@defaultScoreFunction)
31
+
32
+ def group(options = {})
33
+ invert_entities(options[:includeFunction] || @@defaultIncludeFunction,
34
+ options[:dynamicTagFunction] || @@dynamicTagFunction)
35
+ count_entities(options[:scoreFunction] || @@defaultScoreFunction)
32
36
  end
33
-
37
+
34
38
  def count_entities(scoreFunction)
35
39
  map = BSON::Code.new(<<eos)
36
- function() {
37
- score = #{scoreFunction};
38
- tag = this._id.tag;
39
- tagScore = score(tag);
40
- entities = this.value.entities.slice(0).sort();
41
- for (x in entities) {
42
- for (y in entities) {
43
- if (x < y) {
44
- emit({tag:tag, e:[entities[x], entities[y]]}, {count:tagScore});
45
- emit({e:[entities[x], entities[y]]}, {count:tagScore});
46
- }
47
- }
48
- }
49
- }
40
+ function() {
41
+ var score = #{scoreFunction},
42
+ tag = this._id.tag,
43
+ tagScore = score(tag),
44
+ entities = this.value.entities.slice(0).sort();
45
+ for (x in entities) {
46
+ for (y in entities) {
47
+ if (x < y) {
48
+ emit({tag:tag, e:[entities[x], entities[y]]}, {count:tagScore});
49
+ emit({e:[entities[x], entities[y]]}, {count:tagScore});
50
+ }
51
+ }
52
+ }
53
+ }
50
54
  eos
51
55
 
52
56
  reduce = BSON::Code.new(<<eos)
53
- function(key, values) {
54
- result = {count:0};
55
- values.forEach(function(value) {
56
- result.count += value.count;
57
- });
58
- return result;
59
- }
57
+ function(key, values) {
58
+ var result = {count:0};
59
+ values.forEach(function(value) {
60
+ result.count += value.count;
61
+ });
62
+ return result;
63
+ }
60
64
  eos
61
-
62
- @database["#{@entity}_invert"].map_reduce(map, reduce, :out => "#{@entity}_count")
65
+
66
+ @database["#{@entity}_invert"].find.map_reduce(map, reduce, out: "#{@entity}_count").execute
63
67
  nil
64
68
  end
65
-
69
+
66
70
  def invert_entities(includeFunction, dynamicTagFunction)
67
71
  map = BSON::Code.new(<<eos)
68
- function() {
69
- include = #{includeFunction};
70
- dynamicTagFunction = #{dynamicTagFunction};
71
- entity_id = this._id;
72
- if (this.tags) {
73
- for (tag in this.tags) {
74
- if (!include(tag)) continue;
75
- this.tags[tag].forEach(function(z) {
76
- emit({tag:tag, value:z}, {entities: [entity_id]});
72
+ function() {
73
+ var include = #{includeFunction},
74
+ dynamicTagFunction = #{dynamicTagFunction},
75
+ entity_id = this._id;
76
+ if (this.tags) {
77
+ for (tag in this.tags) {
78
+ if (!include(tag)) continue;
79
+ this.tags[tag].forEach(function(z) {
80
+ emit({tag:tag, value:z}, {entities: [entity_id]});
77
81
  });
78
82
  }
79
83
  dynamicTagFunction(this);
80
- }
84
+ }
81
85
  }
82
86
  eos
83
-
87
+
84
88
  reduce = BSON::Code.new(<<eos)
85
- function(key, values) {
86
- result = {entities:[]};
87
- values.forEach(function(value) {
88
- value['entities'].forEach(function(entity_id) {
89
- result['entities'].push( entity_id );
90
- });
91
- });
92
- return result;
89
+ function(key, values) {
90
+ var result = {entities:[]};
91
+ values.forEach(function(value) {
92
+ value['entities'].forEach(function(entity_id) {
93
+ result['entities'].push( entity_id );
94
+ });
95
+ });
96
+ return result;
93
97
  }
94
98
  eos
95
-
96
- @database[@entity].map_reduce(map, reduce, :out => "#{@entity}_invert")
99
+ @database[@entity].find.map_reduce(map, reduce, out: "#{@entity}_invert").execute
97
100
  nil
98
101
  end
99
-
100
102
  end
101
- end
103
+ end
metadata CHANGED
@@ -1,193 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rugroupy
3
- version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 2
10
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Ryan Wynn
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-08-22 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- requirement: &id001 !ruby/object:Gem::Requirement
22
- none: false
23
- requirements:
11
+ date: 2018-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bson
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
24
17
  - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 25
27
- segments:
28
- - 1
29
- - 3
30
- - 1
31
- version: 1.3.1
32
- version_requirements: *id001
33
- name: mongo
34
- prerelease: false
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
35
20
  type: :runtime
36
- - !ruby/object:Gem::Dependency
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 25
43
- segments:
44
- - 1
45
- - 3
46
- - 1
47
- version: 1.3.1
48
- version_requirements: *id002
49
- name: bson
50
21
  prerelease: false
51
- type: :runtime
52
- - !ruby/object:Gem::Dependency
53
- requirement: &id003 !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
56
24
  - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 25
59
- segments:
60
- - 1
61
- - 3
62
- - 1
63
- version: 1.3.1
64
- version_requirements: *id003
65
- name: bson_ext
66
- prerelease: false
67
- type: :runtime
68
- - !ruby/object:Gem::Dependency
69
- requirement: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mongo
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
72
31
  - - ">="
73
- - !ruby/object:Gem::Version
74
- hash: 25
75
- segments:
76
- - 1
77
- - 2
78
- - 3
79
- version: 1.2.3
80
- version_requirements: *id004
81
- name: SystemTimer
82
- prerelease: false
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
83
34
  type: :runtime
84
- - !ruby/object:Gem::Dependency
85
- requirement: &id005 !ruby/object:Gem::Requirement
86
- none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- hash: 3
91
- segments:
92
- - 0
93
- version: "0"
94
- version_requirements: *id005
95
- name: shoulda
96
35
  prerelease: false
97
- type: :development
98
- - !ruby/object:Gem::Dependency
99
- requirement: &id006 !ruby/object:Gem::Requirement
100
- none: false
101
- requirements:
102
- - - ~>
103
- - !ruby/object:Gem::Version
104
- hash: 23
105
- segments:
106
- - 1
107
- - 0
108
- - 0
109
- version: 1.0.0
110
- version_requirements: *id006
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
111
42
  name: bundler
112
- prerelease: false
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
113
48
  type: :development
114
- - !ruby/object:Gem::Dependency
115
- requirement: &id007 !ruby/object:Gem::Requirement
116
- none: false
117
- requirements:
118
- - - ~>
119
- - !ruby/object:Gem::Version
120
- hash: 7
121
- segments:
122
- - 1
123
- - 6
124
- - 4
125
- version: 1.6.4
126
- version_requirements: *id007
127
- name: jeweler
128
49
  prerelease: false
129
- type: :development
130
- - !ruby/object:Gem::Dependency
131
- requirement: &id008 !ruby/object:Gem::Requirement
132
- none: false
133
- requirements:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
134
59
  - - ">="
135
- - !ruby/object:Gem::Version
136
- hash: 3
137
- segments:
138
- - 0
139
- version: "0"
140
- version_requirements: *id008
141
- name: rcov
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
142
63
  prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: shoulda
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
143
76
  type: :development
144
- description: a library which uses the map-reduce capabilities of mongodb to group entities based on tags.
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: a library which uses the map-reduce capabilities of mongodb to group
84
+ entities based on tags.
145
85
  email: ryan.m.wynn@gmail.com
146
86
  executables: []
147
-
148
87
  extensions: []
149
-
150
- extra_rdoc_files:
88
+ extra_rdoc_files:
89
+ - LICENSE.txt
90
+ - README.rdoc
91
+ files:
151
92
  - LICENSE.txt
152
93
  - README.rdoc
153
- files:
154
94
  - lib/rugroupy.rb
155
95
  - lib/rugroupy/entity.rb
156
96
  - lib/rugroupy/group.rb
157
- - LICENSE.txt
158
- - README.rdoc
159
97
  homepage: http://github.com/rwynn/rugroupy
160
- licenses:
98
+ licenses:
161
99
  - MIT
100
+ metadata: {}
162
101
  post_install_message:
163
102
  rdoc_options: []
164
-
165
- require_paths:
103
+ require_paths:
166
104
  - lib
167
- required_ruby_version: !ruby/object:Gem::Requirement
168
- none: false
169
- requirements:
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
170
107
  - - ">="
171
- - !ruby/object:Gem::Version
172
- hash: 3
173
- segments:
174
- - 0
175
- version: "0"
176
- required_rubygems_version: !ruby/object:Gem::Requirement
177
- none: false
178
- requirements:
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
179
112
  - - ">="
180
- - !ruby/object:Gem::Version
181
- hash: 3
182
- segments:
183
- - 0
184
- version: "0"
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
185
115
  requirements: []
186
-
187
116
  rubyforge_project:
188
- rubygems_version: 1.8.6
117
+ rubygems_version: 2.2.2
189
118
  signing_key:
190
- specification_version: 3
119
+ specification_version: 4
191
120
  summary: find things that are similiar to things
192
121
  test_files: []
193
-