supernova 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/supernova/solr_criteria.rb +20 -1
- data/lib/supernova/solr_indexer.rb +2 -2
- data/spec/integration/solr_spec.rb +38 -31
- data/spec/supernova/solr_criteria_spec.rb +37 -0
- data/spec/supernova/solr_indexer_spec.rb +8 -2
- data/supernova.gemspec +1 -1
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.4
|
@@ -48,6 +48,15 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
48
48
|
Supernova::SolrIndexer.solr_field_for_field_name_and_mapping(field, search_options[:attribute_mapping])
|
49
49
|
end
|
50
50
|
|
51
|
+
def reverse_lookup_solr_field(solr_field)
|
52
|
+
if search_options[:attribute_mapping]
|
53
|
+
search_options[:attribute_mapping].each do |field, options|
|
54
|
+
return field if solr_field.to_s == solr_field_from_field(field)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
solr_field
|
58
|
+
end
|
59
|
+
|
51
60
|
def fq_from_with(with)
|
52
61
|
if with.blank?
|
53
62
|
[]
|
@@ -85,7 +94,7 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
85
94
|
if key == "id"
|
86
95
|
doc.id = value.to_s.split("/").last if doc.respond_to?(:id=)
|
87
96
|
else
|
88
|
-
doc
|
97
|
+
set_first_responding_attribute(doc, key, value)
|
89
98
|
end
|
90
99
|
end
|
91
100
|
doc.instance_variable_set("@readonly", true)
|
@@ -93,6 +102,16 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
93
102
|
doc
|
94
103
|
end
|
95
104
|
|
105
|
+
def set_first_responding_attribute(doc, solr_key, value)
|
106
|
+
[reverse_lookup_solr_field(solr_key), solr_key].each do |key|
|
107
|
+
meth = :"#{key}="
|
108
|
+
if doc.respond_to?(meth)
|
109
|
+
doc.send(meth, value)
|
110
|
+
return
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
96
115
|
def to_a
|
97
116
|
response = Supernova::Solr.connection.get("select", :params => to_params)
|
98
117
|
collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
|
@@ -12,7 +12,7 @@ class Supernova::SolrIndexer
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def has(key, attributes)
|
15
|
-
field_definitions[key] = attributes
|
15
|
+
field_definitions[key] = attributes.is_a?(Hash) ? attributes : { :type => attributes }
|
16
16
|
end
|
17
17
|
|
18
18
|
def clazz(class_name =:only_return)
|
@@ -190,6 +190,6 @@ class Supernova::SolrIndexer
|
|
190
190
|
else
|
191
191
|
%(cd #{File.dirname(index_file_path)} && curl -s '#{solr_url}/update/json?commit=true' --data-binary @#{File.basename(index_file_path)} -H 'Content-type:application/json')
|
192
192
|
end
|
193
|
-
|
193
|
+
Kernel.send(:`, cmd)
|
194
194
|
end
|
195
195
|
end
|
@@ -10,11 +10,13 @@ describe "Solr" do
|
|
10
10
|
# endpoint = root.endpoint(90, 50, :units => :kms)
|
11
11
|
e_lat = 46.9981112912042
|
12
12
|
e_lng = 11.6587158814378
|
13
|
-
Supernova::Solr.connection.add(:id => "offers/1", :type => "Offer", :
|
14
|
-
:
|
13
|
+
Supernova::Solr.connection.add(:id => "offers/1", :type => "Offer", :user_id_i => 1, :enabled_b => false,
|
14
|
+
:text_t => "Hans Meyer", :popularity_i => 10,
|
15
|
+
:location_p => "#{root.lat},#{root.lng}", :type => "Offer"
|
15
16
|
)
|
16
|
-
Supernova::Solr.connection.add(:id => "offers/2", :
|
17
|
-
:
|
17
|
+
Supernova::Solr.connection.add(:id => "offers/2", :user_id_i => 2, :enabled_b => true, :text_t => "Marek Mintal",
|
18
|
+
:popularity_i => 1,
|
19
|
+
:location_p => "#{e_lat},#{e_lng}", :type => "Offer"
|
18
20
|
)
|
19
21
|
Supernova::Solr.connection.commit
|
20
22
|
end
|
@@ -48,27 +50,27 @@ describe "Solr" do
|
|
48
50
|
|
49
51
|
describe "plain text search" do
|
50
52
|
it "returns the correct entries for 1 term" do
|
51
|
-
new_criteria.search("Hans").to_a.map { |h| h["id"] }.should == [1]
|
52
|
-
new_criteria.search("Hans").search("Meyer").to_a.map { |h| h["id"] }.should == [1]
|
53
|
-
new_criteria.search("Marek").to_a.map { |h| h["id"] }.should == [2]
|
53
|
+
new_criteria.search("text_t:Hans").to_a.map { |h| h["id"] }.should == [1]
|
54
|
+
new_criteria.search("text_t:Hans").search("text_t:Meyer").to_a.map { |h| h["id"] }.should == [1]
|
55
|
+
new_criteria.search("text_t:Marek").to_a.map { |h| h["id"] }.should == [2]
|
54
56
|
end
|
55
57
|
|
56
58
|
it "returns the correct options for a combined search" do
|
57
|
-
new_criteria.search("Hans", "Marek").to_a.map.should == []
|
59
|
+
new_criteria.search("text_t:Hans", "text_t:Marek").to_a.map.should == []
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
63
|
it "includes the returned solr_doc" do
|
62
|
-
new_criteria.search("Hans").to_a.first.instance_variable_get("@solr_doc").should == {
|
63
|
-
"id" => "offers/1", "type" => "Offer", "
|
64
|
-
"
|
64
|
+
new_criteria.search("text_t:Hans").to_a.first.instance_variable_get("@solr_doc").should == {
|
65
|
+
"id" => "offers/1", "type" => "Offer", "user_id_i" => 1, "enabled_b" => false, "text_t" => "Hans Meyer", "popularity_i" => 10,
|
66
|
+
"location_p" => "47,11"
|
65
67
|
}
|
66
68
|
end
|
67
69
|
|
68
70
|
describe "nearby search" do
|
69
71
|
{ 49.kms => 1, 51.kms => 2 }.each do |distance, total_entries|
|
70
72
|
it "returns #{total_entries} for distance #{distance}" do
|
71
|
-
new_criteria.near(47, 11).within(distance).to_a.total_entries.should == total_entries
|
73
|
+
new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).to_a.total_entries.should == total_entries
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
@@ -76,54 +78,59 @@ describe "Solr" do
|
|
76
78
|
describe "range search" do
|
77
79
|
{ Range.new(2, 3) => [2], Range.new(3, 10) => [], Range.new(1, 2) => [1, 2] }.each do |range, ids|
|
78
80
|
it "returns #{ids.inspect} for range #{range.inspect}" do
|
79
|
-
new_criteria.with(:
|
81
|
+
new_criteria.with(:user_id_i => range).map { |doc| doc["id"] }.sort.should == ids
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
86
|
describe "not searches" do
|
85
87
|
it "finds the correct documents for not nil" do
|
86
|
-
Supernova::Solr.connection.add(:id => "offers/3", :
|
88
|
+
Supernova::Solr.connection.add(:id => "offers/3", :enabled_b => true, :text_t => "Marek Mintal", :popularity_i => 1,
|
87
89
|
:type => "Offer"
|
88
90
|
)
|
89
91
|
Supernova::Solr.connection.commit
|
90
92
|
raise "There should be 3 docs" if new_criteria.to_a.total_entries != 3
|
91
|
-
new_criteria.with(:
|
93
|
+
new_criteria.with(:user_id_i.not => nil).to_a.map { |h| h["id"] }.should == [1, 2]
|
92
94
|
end
|
93
95
|
|
94
96
|
it "finds the correct values for not specific value" do
|
95
|
-
new_criteria.with(:
|
97
|
+
new_criteria.with(:user_id_i.not => 1).to_a.map { |h| h["id"] }.should == [2]
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
101
|
describe "gt and lt searches" do
|
100
102
|
{ :gt => [2], :gte => [1, 2], :lt => [], :lte => [1] }.each do |type, ids|
|
101
103
|
it "finds ids #{ids.inspect} for #{type}" do
|
102
|
-
new_criteria.with(:
|
104
|
+
new_criteria.with(:user_id_i.send(type) => 1).to_a.map { |row| row["id"] }.sort.should == ids
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
109
|
it "returns the correct objects" do
|
108
|
-
new_criteria.with(:
|
110
|
+
new_criteria.with(:user_id_i => 1).to_a.first.should be_an_instance_of(Offer)
|
109
111
|
end
|
110
112
|
|
111
113
|
{ :id => 1, :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10 }.each do |key, value|
|
112
114
|
it "sets #{key} to #{value}" do
|
113
|
-
doc = new_criteria.
|
115
|
+
doc = new_criteria.attribute_mapping(
|
116
|
+
:user_id => { :type => :integer },
|
117
|
+
:enabled => { :type => :boolean },
|
118
|
+
:popularity => { :type => :integer },
|
119
|
+
:text => { :type => :text}
|
120
|
+
).with(:id => "offers/1").to_a.first
|
114
121
|
doc.send(key).should == value
|
115
122
|
end
|
116
123
|
end
|
117
124
|
|
118
125
|
it "combines filters" do
|
119
|
-
new_criteria.with(:
|
120
|
-
new_criteria.with(:
|
126
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).to_a.total_entries.should == 1
|
127
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => true).to_a.total_entries.should == 0
|
121
128
|
end
|
122
129
|
|
123
130
|
it "uses without correctly" do
|
124
|
-
new_criteria.without(:
|
125
|
-
new_criteria.without(:
|
126
|
-
new_criteria.without(:
|
131
|
+
new_criteria.without(:user_id_i => 1).to_a.map(&:id).should == [2]
|
132
|
+
new_criteria.without(:user_id_i => 2).to_a.map(&:id).should == [1]
|
133
|
+
new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).to_a.map(&:id).should == []
|
127
134
|
end
|
128
135
|
|
129
136
|
it "uses the correct orders" do
|
@@ -132,25 +139,25 @@ describe "Solr" do
|
|
132
139
|
end
|
133
140
|
|
134
141
|
it "uses the correct pagination attributes" do
|
135
|
-
new_criteria.with(:
|
136
|
-
new_criteria.with(:
|
137
|
-
new_criteria.with(:
|
138
|
-
new_criteria.with(:
|
142
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).to_a.total_entries.should == 1
|
143
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).length.should == 1
|
144
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).to_a.total_entries.should == 1
|
145
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).length.should == 0
|
139
146
|
|
140
147
|
new_criteria.paginate(:per_page => 1, :page => 1).to_a.map(&:id).should == [1]
|
141
148
|
new_criteria.paginate(:per_page => 1, :page => 2).to_a.map(&:id).should == [2]
|
142
149
|
end
|
143
150
|
|
144
151
|
it "handels empty results correctly" do
|
145
|
-
results = new_criteria.with(:
|
152
|
+
results = new_criteria.with(:user_id_i => 1, :enabled_b => true).to_a
|
146
153
|
results.total_entries.should == 0
|
147
154
|
results.current_page.should == 1
|
148
155
|
end
|
149
156
|
|
150
157
|
it "only sets specific attributes" do
|
151
|
-
results = new_criteria.select(:
|
158
|
+
results = new_criteria.select(:user_id_i).with(:user_id_i => 1).to_a
|
152
159
|
results.length.should == 1
|
153
|
-
results.first.should == { "id" => "offers/1", "
|
160
|
+
results.first.should == { "id" => "offers/1", "user_id_i" => 1 }
|
154
161
|
end
|
155
162
|
end
|
156
163
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require "ostruct"
|
2
3
|
|
3
4
|
describe Supernova::SolrCriteria do
|
4
5
|
let(:criteria) { Supernova::SolrCriteria.new }
|
@@ -286,6 +287,13 @@ describe Supernova::SolrCriteria do
|
|
286
287
|
criteria.build_doc(docs.first).should_not be_a_new_record
|
287
288
|
end
|
288
289
|
|
290
|
+
it "uses attribute_mapping when defined" do
|
291
|
+
criteria.attribute_mapping(:enabled => { :type => :boolean }, :popularity => { :type => :integer })
|
292
|
+
doc = criteria.build_doc("type" => "Offer", "id" => "offers/1", "enabled_b" => true, "popularity_i" => 10)
|
293
|
+
doc.should be_an_instance_of(Offer)
|
294
|
+
doc.popularity.should == 10
|
295
|
+
end
|
296
|
+
|
289
297
|
class MongoOffer
|
290
298
|
attr_accessor :id
|
291
299
|
end
|
@@ -301,6 +309,35 @@ describe Supernova::SolrCriteria do
|
|
301
309
|
end
|
302
310
|
end
|
303
311
|
|
312
|
+
describe "#reverse_lookup_solr_field" do
|
313
|
+
it "returns the key when no mapping found" do
|
314
|
+
Supernova::SolrCriteria.new.reverse_lookup_solr_field(:artist_id_s).should == :artist_id_s
|
315
|
+
end
|
316
|
+
|
317
|
+
it "returns the correct original key when mapped" do
|
318
|
+
criteria.attribute_mapping(:artist_name => { :type => :string }).reverse_lookup_solr_field(:artist_name_s).should == :artist_name
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
describe "#set_first_responding_attribute" do
|
323
|
+
it "sets the reverse looked up attribute when found" do
|
324
|
+
doc = OpenStruct.new(:artist_name => nil)
|
325
|
+
criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
|
326
|
+
doc.artist_name.should == "Mos Def"
|
327
|
+
end
|
328
|
+
|
329
|
+
it "sets the original key when no mapping defined" do
|
330
|
+
doc = OpenStruct.new(:artist_name_s => nil)
|
331
|
+
criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
|
332
|
+
doc.artist_name_s.should == "Mos Def"
|
333
|
+
end
|
334
|
+
|
335
|
+
it "does not break on unknown keys" do
|
336
|
+
doc = double("dummy")
|
337
|
+
criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
304
341
|
describe "#current_page" do
|
305
342
|
it "returns 1 when pagiantion is not set" do
|
306
343
|
criteria.current_page.should == 1
|
@@ -25,6 +25,7 @@ describe Supernova::SolrIndexer do
|
|
25
25
|
|
26
26
|
before(:each) do
|
27
27
|
File.stub!(:open).and_return file_stub
|
28
|
+
Kernel.stub!(:`).and_return true
|
28
29
|
end
|
29
30
|
|
30
31
|
describe "initialize" do
|
@@ -238,14 +239,14 @@ describe Supernova::SolrIndexer do
|
|
238
239
|
|
239
240
|
it "calls the correct curl command" do
|
240
241
|
indexer.index_file_path = "/tmp/some_path.json"
|
241
|
-
|
242
|
+
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'")
|
242
243
|
indexer.do_index_file(:local => true)
|
243
244
|
end
|
244
245
|
|
245
246
|
it "executes the correct curl call when not local" do
|
246
247
|
# curl 'http://localhost:8983/solr/update/json?commit=true' --data-binary @books.json -H 'Content-type:application/json'
|
247
248
|
indexer.index_file_path = "/tmp/some_path.json"
|
248
|
-
|
249
|
+
Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'")
|
249
250
|
indexer.do_index_file
|
250
251
|
end
|
251
252
|
end
|
@@ -262,6 +263,11 @@ describe Supernova::SolrIndexer do
|
|
262
263
|
blank_indexer_clazz.field_definitions.should == { :artist_id => { :type => :integer, :sortable => true } }
|
263
264
|
end
|
264
265
|
|
266
|
+
it "has can also be called with a symbol as argument and sets that to the type" do
|
267
|
+
blank_indexer_clazz.has(:artist_id, :integer)
|
268
|
+
blank_indexer_clazz.field_definitions.should == { :artist_id => { :type => :integer } }
|
269
|
+
end
|
270
|
+
|
265
271
|
it "clazz sets indexed class" do
|
266
272
|
blank_indexer_clazz.clazz(Integer)
|
267
273
|
blank_indexer_clazz.instance_variable_get("@clazz").should == Integer
|
data/supernova.gemspec
CHANGED
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 4
|
10
|
+
version: 0.3.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tobias Schwab
|