supernova 0.4.18 → 0.6.0

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.
data/Gemfile CHANGED
@@ -9,10 +9,10 @@ source "http://rubygems.org"
9
9
  gem "rsolr"
10
10
  gem "will_paginate"
11
11
  gem "json"
12
- gem "i18n"
13
12
  gem "activesupport"
14
13
 
15
14
  group :development do
15
+ gem "i18n"
16
16
  gem 'activerecord', '~>3.0.7', :require => "active_record"
17
17
  gem "ruby-debug"
18
18
  gem "mysql2", "~> 0.2.7"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.18
1
+ 0.6.0
@@ -1,4 +1,5 @@
1
1
  require "will_paginate"
2
2
 
3
3
  class Supernova::Collection < WillPaginate::Collection
4
+ attr_accessor :original_response, :facets
4
5
  end
@@ -69,6 +69,10 @@ class Supernova::Criteria
69
69
  def select(*fields)
70
70
  merge_filters_array :select, fields
71
71
  end
72
+
73
+ def facet_fields(*fields)
74
+ merge_filters_array :facets, fields
75
+ end
72
76
 
73
77
  def conditions(filters)
74
78
  merge_filters :conditions, filters
@@ -27,6 +27,11 @@ class Supernova::SolrCriteria < Supernova::Criteria
27
27
  end
28
28
  solr_options[:fq] << "type:#{self.clazz}" if self.clazz
29
29
 
30
+ if self.search_options[:facets]
31
+ solr_options[:facet] = true
32
+ solr_options["facet.field"] = self.search_options[:facets].compact.map { |field| solr_field_from_field(field) }
33
+ end
34
+
30
35
  if self.search_options[:pagination]
31
36
  solr_options[:rows] = per_page
32
37
  solr_options[:start] = (current_page - 1) * solr_options[:rows]
@@ -142,9 +147,20 @@ class Supernova::SolrCriteria < Supernova::Criteria
142
147
  end
143
148
  end
144
149
 
150
+ def hashify_facets_from_response(response)
151
+ if response["facet_counts"] && response["facet_counts"]["facet_fields"]
152
+ response["facet_counts"]["facet_fields"].inject({}) do |hash, (key, values)|
153
+ hash[reverse_lookup_solr_field(key)] = Hash[*values]
154
+ hash
155
+ end
156
+ end
157
+ end
158
+
145
159
  def execute
146
160
  response = Supernova::Solr.connection.post("select", :data => to_params)
147
161
  collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
162
+ collection.original_response = response
163
+ collection.facets = hashify_facets_from_response(response)
148
164
  collection.replace(build_docs(response["response"]["docs"]))
149
165
  collection
150
166
  end
@@ -240,4 +240,31 @@ describe "Solr" do
240
240
  results.first.should == { "id" => "offers/1", "user_id_i" => 1 }
241
241
  end
242
242
  end
243
+
244
+ describe "#facets" do
245
+ it "returns the correct facets hash" do
246
+ # pending "fix me"
247
+ Supernova::Solr.connection.add(:id => "offers/3", :type => "Offer", :user_id_i => 3, :enabled_b => false,
248
+ :text_t => "Hans Müller", :popularity_i => 10, :type => "Offer"
249
+ )
250
+ Supernova::Solr.connection.commit
251
+ new_criteria.facet_fields(:text_t).execute.facets.should == {"text_t"=>{"mintal"=>1, "marek"=>1, "meyer"=>1, "m\303\274ller"=>1, "han"=>2}}
252
+ end
253
+ end
254
+
255
+ describe "with mapping" do
256
+ before(:each) do
257
+ @clazz = Class.new(Supernova::SolrIndexer)
258
+ @clazz.has :location, :type => :string
259
+ @clazz.has :city, :type => :string
260
+ end
261
+
262
+ it "returns the correct facets" do
263
+ row1 = { "id" => 1, "location" => "Hamburg", "type" => "Offer" }
264
+ row2 = { "id" => 2, "location" => "Hamburg", "type" => "Offer" }
265
+ row3 = { "id" => 3, "location" => "Berlin", "type" => "Offer" }
266
+ @clazz.new.index_rows([row1, row2, row3])
267
+ @clazz.facet_fields(:location).execute.facets.should == { :location=>{ "Berlin"=>1, "Hamburg"=>2 } }
268
+ end
269
+ end
243
270
  end
@@ -29,7 +29,8 @@ describe "Supernova::Criteria" do
29
29
  [:near, "test"],
30
30
  [:within, 10],
31
31
  [:options, {}],
32
- [:without, {}]
32
+ [:without, {}],
33
+ [:facet_fields, "name"]
33
34
  ].each do |args|
34
35
  it "returns the scope itself for #{args.first}" do
35
36
  scope.send(*args).should == scope
@@ -43,6 +44,12 @@ describe "Supernova::Criteria" do
43
44
  end
44
45
  end
45
46
 
47
+ describe "#facet_fields" do
48
+ it "sets the facets" do
49
+ scope.facet_fields("title").facet_fields("name", "first_name").search_options[:facets].should == %w(title name first_name)
50
+ end
51
+ end
52
+
46
53
  describe "#order" do
47
54
  it "sets the order statement" do
48
55
  scope.order("popularity desc").search_options[:order].should == "popularity desc"
@@ -82,7 +82,6 @@ describe Supernova::SolrCriteria do
82
82
  end
83
83
  end
84
84
 
85
-
86
85
  it "sets search correct search query" do
87
86
  criteria.search("some query").to_params[:q].should == "(some query)"
88
87
  end
@@ -104,6 +103,16 @@ describe Supernova::SolrCriteria do
104
103
  criteria.select(:user_id).select(:user_id).select(:enabled).to_params[:fl].should == "user_id,enabled,id"
105
104
  end
106
105
 
106
+ it "sets the correct facet options when set" do
107
+ params = criteria.facet_fields(:name).to_params
108
+ params[:facet].should == true
109
+ end
110
+
111
+ it "sets all facet fields" do
112
+ params = criteria.facet_fields(:name).facet_fields(:title).to_params
113
+ params["facet.field"].should == ["name", "title"]
114
+ end
115
+
107
116
  it "uses mapped fields for select" do
108
117
  mapping = {
109
118
  :user_id => { :type => :integer },
@@ -196,6 +205,10 @@ describe Supernova::SolrCriteria do
196
205
  rsolr.stub!(:post).and_return solr_response
197
206
  end
198
207
 
208
+ it "sets the original response" do
209
+ criteria.execute.original_response.should == solr_response
210
+ end
211
+
199
212
  it "calls to_params" do
200
213
  criteria.should_receive(:to_params).and_return params
201
214
  criteria.execute
@@ -240,13 +253,37 @@ describe Supernova::SolrCriteria do
240
253
  end
241
254
 
242
255
  it "calls replace on collection wit returned docs" do
243
- col = double("collection")
256
+ col = double("collection", :original_response= => true, :facets= => true)
244
257
  Supernova::Collection.stub!(:new).and_return col
245
258
  built_docs = double("built docs")
246
259
  criteria.stub!(:build_docs).and_return built_docs
247
260
  col.should_receive(:replace).with(built_docs)
248
261
  criteria.execute
249
262
  end
263
+
264
+ it "sets the correct facets" do
265
+ rsolr.stub!(:post).and_return facet_response
266
+ criteria.should_receive(:hashify_facets_from_response).with(facet_response).and_return({ :a => 1 })
267
+ criteria.execute.facets.should == {:a => 1}
268
+ end
269
+ end
270
+
271
+ let(:facet_response) {
272
+ {
273
+ "response"=>{"start"=>0, "docs"=>[{"popularity_i"=>10, "enabled_b"=>false, "id"=>"offers/1", "user_id_i"=>1, "text_t"=>"Hans Meyer", "type"=>"Offer", "location_p"=>"47,11"}, {"popularity_i"=>1, "enabled_b"=>true, "id"=>"offers/2", "user_id_i"=>2, "text_t"=>"Marek Mintal", "type"=>"Offer", "location_p"=>"46.9981112912042,11.6587158814378"}], "numFound"=>2}, "facet_counts"=>{"facet_fields"=>{"text_t"=>["han", 1, "marek", 1, "meyer", 1, "mintal", 1]}, "facet_ranges"=>{}, "facet_dates"=>{}, "facet_queries"=>{}}, "responseHeader"=>{"QTime"=>4, "params"=>{"fq"=>"type:Offer", "facet.field"=>"text_t", "facet"=>"true", "q"=>"*:*", "wt"=>"ruby"}, "status"=>0}
274
+ }
275
+ }
276
+
277
+ describe "#hashify_facets_from_response" do
278
+ it "returns nil when nothing found" do
279
+ criteria.hashify_facets_from_response({}).should == nil
280
+ end
281
+
282
+ it "returns the correct hash when facets returned" do
283
+ criteria.hashify_facets_from_response(facet_response).should == {
284
+ "text_t" => { "han" => 1, "marek" => 1, "meyer" => 1, "mintal" => 1 }
285
+ }
286
+ end
250
287
  end
251
288
 
252
289
  describe "#build_docs" do
@@ -5,12 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{supernova}
8
- s.version = "0.4.18"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Schwab"]
12
12
  s.date = %q{2011-08-04}
13
- s.default_executable = %q{start_solr}
14
13
  s.description = %q{Unified search scopes}
15
14
  s.email = %q{tobias.schwab@dynport.de}
16
15
  s.executables = ["start_solr"]
@@ -95,7 +94,7 @@ Gem::Specification.new do |s|
95
94
  s.homepage = %q{http://github.com/dynport/supernova}
96
95
  s.licenses = ["MIT"]
97
96
  s.require_paths = ["lib"]
98
- s.rubygems_version = %q{1.6.2}
97
+ s.rubygems_version = %q{1.7.2}
99
98
  s.summary = %q{Unified search scopes}
100
99
 
101
100
  if s.respond_to? :specification_version then
@@ -105,8 +104,8 @@ Gem::Specification.new do |s|
105
104
  s.add_runtime_dependency(%q<rsolr>, [">= 0"])
106
105
  s.add_runtime_dependency(%q<will_paginate>, [">= 0"])
107
106
  s.add_runtime_dependency(%q<json>, [">= 0"])
108
- s.add_runtime_dependency(%q<i18n>, [">= 0"])
109
107
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
108
+ s.add_development_dependency(%q<i18n>, [">= 0"])
110
109
  s.add_development_dependency(%q<activerecord>, ["~> 3.0.7"])
111
110
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
112
111
  s.add_development_dependency(%q<mysql2>, ["~> 0.2.7"])
@@ -122,8 +121,8 @@ Gem::Specification.new do |s|
122
121
  s.add_dependency(%q<rsolr>, [">= 0"])
123
122
  s.add_dependency(%q<will_paginate>, [">= 0"])
124
123
  s.add_dependency(%q<json>, [">= 0"])
125
- s.add_dependency(%q<i18n>, [">= 0"])
126
124
  s.add_dependency(%q<activesupport>, [">= 0"])
125
+ s.add_dependency(%q<i18n>, [">= 0"])
127
126
  s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
128
127
  s.add_dependency(%q<ruby-debug>, [">= 0"])
129
128
  s.add_dependency(%q<mysql2>, ["~> 0.2.7"])
@@ -140,8 +139,8 @@ Gem::Specification.new do |s|
140
139
  s.add_dependency(%q<rsolr>, [">= 0"])
141
140
  s.add_dependency(%q<will_paginate>, [">= 0"])
142
141
  s.add_dependency(%q<json>, [">= 0"])
143
- s.add_dependency(%q<i18n>, [">= 0"])
144
142
  s.add_dependency(%q<activesupport>, [">= 0"])
143
+ s.add_dependency(%q<i18n>, [">= 0"])
145
144
  s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
146
145
  s.add_dependency(%q<ruby-debug>, [">= 0"])
147
146
  s.add_dependency(%q<mysql2>, ["~> 0.2.7"])
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: supernova
3
3
  version: !ruby/object:Gem::Version
4
- hash: 43
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 18
10
- version: 0.4.18
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Schwab
@@ -15,11 +15,9 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-04 00:00:00 +02:00
19
- default_executable: start_solr
18
+ date: 2011-08-04 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- type: :runtime
23
21
  requirement: &id001 !ruby/object:Gem::Requirement
24
22
  none: false
25
23
  requirements:
@@ -29,11 +27,11 @@ dependencies:
29
27
  segments:
30
28
  - 0
31
29
  version: "0"
32
- name: rsolr
33
30
  version_requirements: *id001
31
+ name: rsolr
34
32
  prerelease: false
35
- - !ruby/object:Gem::Dependency
36
33
  type: :runtime
34
+ - !ruby/object:Gem::Dependency
37
35
  requirement: &id002 !ruby/object:Gem::Requirement
38
36
  none: false
39
37
  requirements:
@@ -43,11 +41,11 @@ dependencies:
43
41
  segments:
44
42
  - 0
45
43
  version: "0"
46
- name: will_paginate
47
44
  version_requirements: *id002
45
+ name: will_paginate
48
46
  prerelease: false
49
- - !ruby/object:Gem::Dependency
50
47
  type: :runtime
48
+ - !ruby/object:Gem::Dependency
51
49
  requirement: &id003 !ruby/object:Gem::Requirement
52
50
  none: false
53
51
  requirements:
@@ -57,11 +55,11 @@ dependencies:
57
55
  segments:
58
56
  - 0
59
57
  version: "0"
60
- name: json
61
58
  version_requirements: *id003
59
+ name: json
62
60
  prerelease: false
63
- - !ruby/object:Gem::Dependency
64
61
  type: :runtime
62
+ - !ruby/object:Gem::Dependency
65
63
  requirement: &id004 !ruby/object:Gem::Requirement
66
64
  none: false
67
65
  requirements:
@@ -71,11 +69,11 @@ dependencies:
71
69
  segments:
72
70
  - 0
73
71
  version: "0"
74
- name: i18n
75
72
  version_requirements: *id004
73
+ name: activesupport
76
74
  prerelease: false
77
- - !ruby/object:Gem::Dependency
78
75
  type: :runtime
76
+ - !ruby/object:Gem::Dependency
79
77
  requirement: &id005 !ruby/object:Gem::Requirement
80
78
  none: false
81
79
  requirements:
@@ -85,11 +83,11 @@ dependencies:
85
83
  segments:
86
84
  - 0
87
85
  version: "0"
88
- name: activesupport
89
86
  version_requirements: *id005
87
+ name: i18n
90
88
  prerelease: false
91
- - !ruby/object:Gem::Dependency
92
89
  type: :development
90
+ - !ruby/object:Gem::Dependency
93
91
  requirement: &id006 !ruby/object:Gem::Requirement
94
92
  none: false
95
93
  requirements:
@@ -101,11 +99,11 @@ dependencies:
101
99
  - 0
102
100
  - 7
103
101
  version: 3.0.7
104
- name: activerecord
105
102
  version_requirements: *id006
103
+ name: activerecord
106
104
  prerelease: false
107
- - !ruby/object:Gem::Dependency
108
105
  type: :development
106
+ - !ruby/object:Gem::Dependency
109
107
  requirement: &id007 !ruby/object:Gem::Requirement
110
108
  none: false
111
109
  requirements:
@@ -115,11 +113,11 @@ dependencies:
115
113
  segments:
116
114
  - 0
117
115
  version: "0"
118
- name: ruby-debug
119
116
  version_requirements: *id007
117
+ name: ruby-debug
120
118
  prerelease: false
121
- - !ruby/object:Gem::Dependency
122
119
  type: :development
120
+ - !ruby/object:Gem::Dependency
123
121
  requirement: &id008 !ruby/object:Gem::Requirement
124
122
  none: false
125
123
  requirements:
@@ -131,11 +129,11 @@ dependencies:
131
129
  - 2
132
130
  - 7
133
131
  version: 0.2.7
134
- name: mysql2
135
132
  version_requirements: *id008
133
+ name: mysql2
136
134
  prerelease: false
137
- - !ruby/object:Gem::Dependency
138
135
  type: :development
136
+ - !ruby/object:Gem::Dependency
139
137
  requirement: &id009 !ruby/object:Gem::Requirement
140
138
  none: false
141
139
  requirements:
@@ -147,11 +145,11 @@ dependencies:
147
145
  - 5
148
146
  - 0
149
147
  version: 4.5.0
150
- name: ZenTest
151
148
  version_requirements: *id009
149
+ name: ZenTest
152
150
  prerelease: false
153
- - !ruby/object:Gem::Dependency
154
151
  type: :development
152
+ - !ruby/object:Gem::Dependency
155
153
  requirement: &id010 !ruby/object:Gem::Requirement
156
154
  none: false
157
155
  requirements:
@@ -161,11 +159,11 @@ dependencies:
161
159
  segments:
162
160
  - 0
163
161
  version: "0"
164
- name: geokit
165
162
  version_requirements: *id010
163
+ name: geokit
166
164
  prerelease: false
167
- - !ruby/object:Gem::Dependency
168
165
  type: :development
166
+ - !ruby/object:Gem::Dependency
169
167
  requirement: &id011 !ruby/object:Gem::Requirement
170
168
  none: false
171
169
  requirements:
@@ -175,11 +173,11 @@ dependencies:
175
173
  segments:
176
174
  - 0
177
175
  version: "0"
178
- name: autotest
179
176
  version_requirements: *id011
177
+ name: autotest
180
178
  prerelease: false
181
- - !ruby/object:Gem::Dependency
182
179
  type: :development
180
+ - !ruby/object:Gem::Dependency
183
181
  requirement: &id012 !ruby/object:Gem::Requirement
184
182
  none: false
185
183
  requirements:
@@ -189,11 +187,11 @@ dependencies:
189
187
  segments:
190
188
  - 0
191
189
  version: "0"
192
- name: autotest-growl
193
190
  version_requirements: *id012
191
+ name: autotest-growl
194
192
  prerelease: false
195
- - !ruby/object:Gem::Dependency
196
193
  type: :development
194
+ - !ruby/object:Gem::Dependency
197
195
  requirement: &id013 !ruby/object:Gem::Requirement
198
196
  none: false
199
197
  requirements:
@@ -205,11 +203,11 @@ dependencies:
205
203
  - 3
206
204
  - 0
207
205
  version: 2.3.0
208
- name: rspec
209
206
  version_requirements: *id013
207
+ name: rspec
210
208
  prerelease: false
211
- - !ruby/object:Gem::Dependency
212
209
  type: :development
210
+ - !ruby/object:Gem::Dependency
213
211
  requirement: &id014 !ruby/object:Gem::Requirement
214
212
  none: false
215
213
  requirements:
@@ -221,11 +219,11 @@ dependencies:
221
219
  - 0
222
220
  - 0
223
221
  version: 1.0.0
224
- name: bundler
225
222
  version_requirements: *id014
223
+ name: bundler
226
224
  prerelease: false
227
- - !ruby/object:Gem::Dependency
228
225
  type: :development
226
+ - !ruby/object:Gem::Dependency
229
227
  requirement: &id015 !ruby/object:Gem::Requirement
230
228
  none: false
231
229
  requirements:
@@ -237,11 +235,11 @@ dependencies:
237
235
  - 6
238
236
  - 0
239
237
  version: 1.6.0
240
- name: jeweler
241
238
  version_requirements: *id015
239
+ name: jeweler
242
240
  prerelease: false
243
- - !ruby/object:Gem::Dependency
244
241
  type: :development
242
+ - !ruby/object:Gem::Dependency
245
243
  requirement: &id016 !ruby/object:Gem::Requirement
246
244
  none: false
247
245
  requirements:
@@ -251,9 +249,10 @@ dependencies:
251
249
  segments:
252
250
  - 0
253
251
  version: "0"
254
- name: rcov
255
252
  version_requirements: *id016
253
+ name: rcov
256
254
  prerelease: false
255
+ type: :development
257
256
  description: Unified search scopes
258
257
  email: tobias.schwab@dynport.de
259
258
  executables:
@@ -336,7 +335,6 @@ files:
336
335
  - spec/supernova/symbol_extensions_spec.rb
337
336
  - spec/supernova_spec.rb
338
337
  - supernova.gemspec
339
- has_rdoc: true
340
338
  homepage: http://github.com/dynport/supernova
341
339
  licenses:
342
340
  - MIT
@@ -366,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
366
364
  requirements: []
367
365
 
368
366
  rubyforge_project:
369
- rubygems_version: 1.6.2
367
+ rubygems_version: 1.7.2
370
368
  signing_key:
371
369
  specification_version: 3
372
370
  summary: Unified search scopes