supernova 0.3.3 → 0.3.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.
- 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
|