jruby_streaming_update_solr_server 0.3.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -25,7 +25,6 @@ See the class files for more information, documentation, and examples.
25
25
  #
26
26
  # doc = SolrInputDocument.new
27
27
  # doc.add 'title', 'This is the title'
28
- # doc.add :title, 'Another title' # symbols are automatically cast to strings for field name
29
28
  # doc << ['title', "This is yet another title, added with '<<'"]
30
29
  # doc.add 'id', 1
31
30
  # doc.add 'author', ['Mike', 'Bill', 'Molly'] # adds multiple values at once
@@ -38,8 +37,7 @@ See the class files for more information, documentation, and examples.
38
37
  # suss = StreamingUpdateSolrServer.new(url,queuesize,threads)
39
38
  # hash = {}
40
39
  # hash['title'] = This is the title'
41
- # hash[:id] = 1 # Can also take symbols instead of strings if you like
42
- # hash[:author] = ['Bill', 'Mike'] # Note that we can add multiple values at once
40
+ # hash['author'] = ['Bill', 'Mike'] # Note that we can add multiple values at once
43
41
  # suss << hash
44
42
  # # repeat as desired
45
43
  # suss.commit
@@ -56,20 +54,24 @@ construct Solr documents and send them to Solr all from within the comfort of th
56
54
 
57
55
  Note that you can use threach to multi-thread it all.
58
56
 
59
- == WARNING: Program hangs on for 60 seconds!
60
-
61
- *WARNING*: After your program ends, the StreamingUpdateSolrServer object hangs on for a full minute, presumably
62
- the timeout of the underlying http client object. I haven't figure out how to change this yet.
63
57
 
64
58
  == ToDo
65
59
 
66
60
  * Figure out why the http client hangs on for so long
67
- * Modify SolrInputDocument.add to take a relevancy weight.
68
61
  * More complete examples
69
62
 
70
63
 
71
64
  === CHANGES
72
65
 
66
+ 0.4.1 (2010.09.07)
67
+ * Updated documentation
68
+ * Added access to document-level boost via #boost and #boost=
69
+ * Added access to field-level boost via #fieldBoost and #setFieldBoost
70
+ * Added third parameter to `#add` for field-level boost
71
+ * Added #values
72
+ * Release new gem
73
+
74
+
73
75
  2010.07.09 Added #useJavabin!
74
76
 
75
77
  == Copyright
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.email = "bill@dueber.com"
11
11
  gem.homepage = "http://github.com/billdueber/jruby_streaming_update_solr_server"
12
12
  gem.authors = ["Bill Dueber"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
13
+ gem.add_development_dependency 'bacon', ">=0"
14
14
  gem.add_development_dependency "yard", ">= 0"
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
@@ -20,18 +20,18 @@ rescue LoadError
20
20
  end
21
21
 
22
22
  require 'rake/testtask'
23
- Rake::TestTask.new(:test) do |test|
24
- test.libs << 'lib' << 'test'
25
- test.pattern = 'test/**/test_*.rb'
26
- test.verbose = true
23
+ Rake::TestTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.pattern = 'spec/**/*_spec.rb'
26
+ spec.verbose = true
27
27
  end
28
28
 
29
29
  begin
30
30
  require 'rcov/rcovtask'
31
- Rcov::RcovTask.new do |test|
32
- test.libs << 'test'
33
- test.pattern = 'test/**/test_*.rb'
34
- test.verbose = true
31
+ Rcov::RcovTask.new do |spec|
32
+ spec.libs << 'spec'
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.verbose = true
35
35
  end
36
36
  rescue LoadError
37
37
  task :rcov do
@@ -41,7 +41,7 @@ end
41
41
 
42
42
  task :test => :check_dependencies
43
43
 
44
- task :default => :test
44
+ task :default => :spec
45
45
 
46
46
  begin
47
47
  require 'yard'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.1
@@ -67,7 +67,7 @@ class StreamingUpdateSolrServer
67
67
  # Add a document to the SUSS
68
68
  # @param [SolrInputDocument, #each_pair] doc The SolrInputDocument or hash (or hash-like object
69
69
  # that responds to #each_pair) to add. The latter must be of the form solrfield => value or
70
- # solrfield => [list, of, values]. They keys can be either symbols or strings.
70
+ # solrfield => [list, of, values]. They keys must be strings.
71
71
  #
72
72
  # @example Create and add a SolrInputDocument
73
73
  # url = 'http://solrmachine:port/solr' # URL to solr
@@ -88,8 +88,7 @@ class StreamingUpdateSolrServer
88
88
  # suss = StreamingUpdateSolrServer.new(url,queuesize,threads)
89
89
  # doc = {}
90
90
  # doc['title'] = This is the title'
91
- # doc[:id] = 1 # Can also take symbols instead of strings if you like
92
- # doc[:author] = ['Bill', 'Mike']
91
+ # doc['author'] = ['Bill', 'Mike']
93
92
  # suss << doc
94
93
  # # repeat as desired
95
94
  # suss.commit
@@ -116,18 +115,62 @@ end
116
115
  #
117
116
  # @author Bill Dueber
118
117
 
118
+ # SolrInputDocument is a wrapper around the {http://lucene.apache.org/solr/api/org/apache/solr/common/SolrInputDocument.html Java SolrInputDocument}.
119
+ # In addition to the methods below, you can call the java methods directly. Common ones are:
120
+ # * `#clear` to empty the document
121
+ # * `#size` to get the number of k-v pairs
122
+ # * `#boost` and `#boost=` to get and set the document-level boost
123
+
119
124
  class SolrInputDocument
125
+
126
+
127
+ # Get the document boost for this document
128
+ # @return [Float] the current document boost
129
+ alias_method :boost, :getDocumentBoost
130
+
131
+ # Set the document boost
132
+ # @param [Float] boost The boost for the document
133
+ # @return [Float] the new boost
134
+
135
+ alias_method :boost=, :setDocumentBoost
136
+
137
+
138
+ # Boost a field. Does nothing if the field does not exist
139
+ # @param [String] field The name of the field
140
+ # @param [Float] boost The new boost
141
+ # @return [Float] the new boost
142
+
143
+ def setFieldBoost field, boost
144
+ f = self.get(field)
145
+ if f
146
+ f.setBoost(boost)
147
+ return boost
148
+ else
149
+ return nil
150
+ end
151
+ end
152
+
153
+ # get the field boost
154
+ # @param [String] field The field whose boost you want
155
+ # @return [Float] The boost
156
+
157
+ def fieldBoost field
158
+ f = self.get(field)
159
+ if f
160
+ return f.getBoost
161
+ else
162
+ return nil
163
+ end
164
+ end
120
165
 
121
166
  # Add a value to a field. Will add all elements of an array in turn
122
- # @param [Symbol, String] field The field to add a value or values to
167
+ # @param [String] field The field to add a value or values to
123
168
  # @param [String, Numeric, #each] val The value or array-like of values to add.
169
+ # @param [Float] boost The boost for this field
124
170
  # @return [Array<String,Numeric>] An array of the field's values after this addition
125
171
 
126
- def add(field, val)
172
+ def add(field, val, boost=nil)
127
173
  return if val == nil
128
- if field.is_a?(Symbol)
129
- field = field.to_s
130
- end
131
174
  if val.is_a? String or val.is_a? Numeric
132
175
  self.addField(field, val)
133
176
  else
@@ -137,13 +180,14 @@ class SolrInputDocument
137
180
  raise NoMethodError, "SolrInputDocument values must be a string, numeric, or an array-like (responds to #each) of same, not #{val.inspect}"
138
181
  end
139
182
  end
140
- self[field]
183
+ self.boost = boost if boost
184
+ return self[field]
141
185
  end
142
186
 
143
187
 
144
- # An alternate syntax for #add, which will usuall be preferred.
188
+ # An alternate syntax for #add.
145
189
  #
146
- # @param [Array<Symbol, String>] fv A two-element array of the form [field, value] or [field, [value1, value2, ...]]
190
+ # @param [Array<String>] fv A two-element array of Strings of the form [field, value] or [field, [value1, value2, ...]]
147
191
  # @return [Array<String>] the list of current values for the field in fv[0]
148
192
  #
149
193
  # @example Add some fields
@@ -162,13 +206,10 @@ class SolrInputDocument
162
206
  #
163
207
  # Note that this will always return either nil (not found) or an array, even of one element
164
208
  #
165
- # @param [String, Symbol] field The field whose values you want (as String or Symbol)
209
+ # @param [String] field The field whose values you want (as String)
166
210
  # @return [Array<String>] An array of values (or nil on not found)
167
211
  #
168
212
  def [] field
169
- if field.is_a?(Symbol)
170
- field = field.to_s
171
- end
172
213
  f = self.get(field)
173
214
  return nil if (f == nil)
174
215
  return f.values.to_a
@@ -178,23 +219,20 @@ class SolrInputDocument
178
219
  #
179
220
  # Note that this is destructive; see #<< to add multiple values to a field
180
221
  #
181
- # @param [String, Symbol] field The solr field you're setting the value of
222
+ # @param [String] field The solr field you're setting the value of
182
223
  # @param [String, Array<String>] value The value or array of values to set
183
224
  # @return [Array<String>] The list of values (i.e., either +value+ or +[value]+)
184
225
  #
185
226
  # @example
186
227
  # doc = SolrInputDocument.new
187
- # doc[:id] = 1 #=> [1]
188
- # doc[:author] = 'Mike' #=> ['Mike']
189
- # doc[:author] = 'Bill' #=> ['Bill']
190
- # doc[:author] #=> ['Bill']
228
+ # doc['id'] = 1 #=> [1]
229
+ # doc['author'] = 'Mike' #=> ['Mike']
230
+ # doc['author'] = 'Bill' #=> ['Bill']
231
+ # doc['author'] #=> ['Bill']
191
232
 
192
233
  def []= field, value
193
- if field.is_a?(Symbol)
194
- field = field.to_s
195
- end
196
234
  self.removeField(field)
197
- self.add(field, value)
235
+ self.add(field, value) unless value.nil?
198
236
  end
199
237
 
200
238
 
@@ -206,15 +244,15 @@ class SolrInputDocument
206
244
  #
207
245
  # @example Merge a hash into an existing document
208
246
  # doc = SolrInputDocument.new
209
- # doc << [:author, 'Bill']
247
+ # doc << ['author', 'Bill']
210
248
  # h = {}
211
249
  # h['author'] = 'Mike'
212
250
  # h['id'] = 1
213
- # h[:copies] = ['Grad reference', 'Long-term storage']
251
+ # h['copies'] = ['Grad reference', 'Long-term storage']
214
252
  # doc.merge! h
215
- # doc[:id] #=> 1
216
- # doc[:author] #=> ['Bill', 'Mike']
217
- # doc[:copies] #=> ['Grad reference', 'Long-term storage']
253
+ # doc['id'] #=> 1
254
+ # doc['author'] #=> ['Bill', 'Mike']
255
+ # doc['copies'] #=> ['Grad reference', 'Long-term storage']
218
256
 
219
257
  def merge! h
220
258
  unless h.respond_to? :each_pair
@@ -241,17 +279,45 @@ class SolrInputDocument
241
279
  return self.keySet.to_a
242
280
  end
243
281
 
282
+ # Get the values as an array
283
+ # @return [Array<String] An array of all the values in all the keys (flattened out)
284
+ #
285
+ alias_method :oldvalues, :values
286
+ def values
287
+ rv = self.keys.map {|k| self[k]}
288
+ rv.uniq!
289
+ rv.flatten!
290
+ return rv
291
+ end
292
+
244
293
  # Does this doc contain the given key?
245
- # @param [Symbol, String] field The field whose presence you want to check
294
+ # @param [String] field The field whose presence you want to check
246
295
  # @return [Boolean] True if the key is present
247
296
 
248
297
  def has_key? field
249
- if field.is_a?(Symbol)
250
- field = field.to_s
251
- end
252
298
  return self.containsKey(field)
253
299
  end
254
300
 
301
+ # Does this doc have the given value?
302
+ # @param [String] value to look for
303
+ # @return [Boolean]
304
+
305
+ def has_value? val
306
+ self.keys.each do |k|
307
+ return true if self[k].include? val
308
+ end
309
+ return false
310
+ end
311
+
312
+ # Delete a key/value pair
313
+ # @param [String] key The key
314
+ # @return [Array<String>] The removed values (or nil)
315
+
316
+ def delete key
317
+ rv = self[key]
318
+ self.removeField key
319
+ return rv
320
+ end
255
321
 
256
322
  end
257
323
 
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe "SolrDocument" do
4
+
5
+ before do
6
+ @doc = SolrInputDocument.new
7
+ end
8
+
9
+ it "starts out empty" do
10
+ @doc.empty?.should.equal true
11
+ @doc.size.should.equal 0
12
+ @doc.values.should.equal []
13
+ @doc.keys.should.equal []
14
+ end
15
+
16
+ it "reports nil for an unset field" do
17
+ @doc['notinhere'].should.equal nil
18
+ end
19
+
20
+ it "sets using =" do
21
+ @doc['t'] = 1
22
+ @doc['t'].should.equal [1]
23
+ @doc['t'] = 2
24
+ @doc['t'].should.equal [2]
25
+ end
26
+
27
+ it "adds using <<" do
28
+ @doc << ['t', 1]
29
+ @doc['t'].should.equal [1]
30
+ @doc << ['t', 2]
31
+ @doc['t'].should.equal [1,2]
32
+ end
33
+
34
+ it "adds items in hash via merge!" do
35
+ @doc << ['id', '1']
36
+ h = {'id' => '2', 'name' => 'Bill'}
37
+ @doc.merge! h
38
+ @doc['id'].should.equal ['1', '2']
39
+ @doc['name'].should.equal ['Bill']
40
+ @doc.values.sort.should.equal ['1', '2','Bill'].sort
41
+ end
42
+
43
+ it "aliases additive_merge! as well" do
44
+ @doc << ['id', 1]
45
+ h = {'id' => 2, 'name' => 'Bill'}
46
+ @doc.additive_merge! h
47
+ @doc['id'].should.equal [1,2]
48
+ @doc['name'].should.equal ['Bill']
49
+ end
50
+
51
+ it "correctly finds keys and values" do
52
+ @doc << ['id', '1']
53
+ @doc << ['name', 'Bill']
54
+ @doc.has_key?('name').should.equal true
55
+ @doc.has_key?('id').should.equal true
56
+ @doc.has_key?('junk').should.equal false
57
+ @doc.has_value?('1').should.equal true
58
+ @doc.has_value?('Bill').should.equal true
59
+ @doc.has_value?('junk').should.equal false
60
+ end
61
+
62
+ it "can add multiple items at once" do
63
+ @doc.add('name', ['Bill', 'Mike', 'Molly'])
64
+ @doc['name'].sort.should.equal ['Bill', 'Mike', 'Molly'].sort
65
+ end
66
+
67
+ it "boosts the doc" do
68
+ @doc.boost = 100
69
+ @doc.boost.should.equal 100
70
+ end
71
+
72
+ it "boosts a field" do
73
+ @doc.add('id', '1')
74
+ @doc.fieldBoost('id').should.equal 1.0
75
+ @doc.setFieldBoost('id', 100.0)
76
+ @doc.fieldBoost('id').should.equal 100.0
77
+ @doc.setFieldBoost('junk', 100.0).should.equal nil
78
+ @doc.fieldBoost('junk').should.equal nil
79
+
80
+ end
81
+
82
+ end
@@ -1,10 +1,14 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
2
+ require 'bacon'
3
+ begin
4
+ require 'greeneggs'
5
+ rescue LoadError
6
+ end
4
7
 
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
8
  $LOAD_PATH.unshift(File.dirname(__FILE__))
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
10
  require 'jruby_streaming_update_solr_server'
8
11
 
9
- class Test::Unit::TestCase
10
- end
12
+ DIR = File.dirname(__FILE__)
13
+
14
+ Bacon.summary_on_exit
metadata CHANGED
@@ -1,46 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jruby_streaming_update_solr_server
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 13
4
5
  prerelease: false
5
6
  segments:
6
- - 0
7
- - 3
8
- - 1
9
- version: 0.3.1
7
+ - 0
8
+ - 4
9
+ - 1
10
+ version: 0.4.1
10
11
  platform: ruby
11
12
  authors:
12
- - Bill Dueber
13
+ - Bill Dueber
13
14
  autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-08-16 00:00:00 -04:00
18
+ date: 2010-09-07 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: thoughtbot-shoulda
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 0
29
- version: "0"
30
- type: :development
31
- version_requirements: *id001
32
- - !ruby/object:Gem::Dependency
33
- name: yard
34
- prerelease: false
35
- requirement: &id002 !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- segments:
40
- - 0
41
- version: "0"
42
- type: :development
43
- version_requirements: *id002
21
+ - !ruby/object:Gem::Dependency
22
+ name: bacon
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
44
49
  description: Some sugar on top of StreamingUpdateSolrServer for use within JRuby
45
50
  email: bill@dueber.com
46
51
  executables: []
@@ -48,52 +53,56 @@ executables: []
48
53
  extensions: []
49
54
 
50
55
  extra_rdoc_files:
51
- - LICENSE
52
- - README.rdoc
56
+ - LICENSE
57
+ - README.rdoc
53
58
  files:
54
- - LICENSE
55
- - README.rdoc
56
- - Rakefile
57
- - VERSION
58
- - jars/apache-solr-solrj-1.5-dev.jar
59
- - jars/commons-codec-1.3.jar
60
- - jars/commons-httpclient-3.1.jar
61
- - jars/commons-logging-1.1.1.jar
62
- - jars/slf4j-api-1.5.5.jar
63
- - jars/slf4j-jdk14-1.5.5 2.jar
64
- - lib/jruby_streaming_update_solr_server.rb
65
- - test/helper.rb
66
- - test/test_jruby_streaming_update_solr_server.rb
59
+ - LICENSE
60
+ - README.rdoc
61
+ - Rakefile
62
+ - VERSION
63
+ - jars/apache-solr-solrj-1.5-dev.jar
64
+ - jars/commons-codec-1.3.jar
65
+ - jars/commons-httpclient-3.1.jar
66
+ - jars/commons-logging-1.1.1.jar
67
+ - jars/slf4j-api-1.5.5.jar
68
+ - jars/slf4j-jdk14-1.5.5 2.jar
69
+ - lib/jruby_streaming_update_solr_server.rb
70
+ - spec/basics_spec.rb
71
+ - spec/spec_helper.rb
67
72
  has_rdoc: true
68
73
  homepage: http://github.com/billdueber/jruby_streaming_update_solr_server
69
74
  licenses: []
70
75
 
71
76
  post_install_message:
72
77
  rdoc_options:
73
- - --charset=UTF-8
78
+ - --charset=UTF-8
74
79
  require_paths:
75
- - lib
80
+ - lib
76
81
  required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
77
83
  requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- segments:
81
- - 0
82
- version: "0"
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
83
90
  required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
84
92
  requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- segments:
88
- - 0
89
- version: "0"
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
90
99
  requirements: []
91
100
 
92
101
  rubyforge_project:
93
- rubygems_version: 1.3.6
102
+ rubygems_version: 1.3.7
94
103
  signing_key:
95
104
  specification_version: 3
96
105
  summary: Simple jruby interface into StreamingUpdateSolrServer
97
106
  test_files:
98
- - test/helper.rb
99
- - test/test_jruby_streaming_update_solr_server.rb
107
+ - spec/basics_spec.rb
108
+ - spec/spec_helper.rb
@@ -1,49 +0,0 @@
1
- require 'helper'
2
-
3
- class TestJrubyStreamingUpdateSolrServer < Test::Unit::TestCase
4
- should "Write some tests, but don't know how to mock up a solr server" do
5
- assert_equal 1, 1
6
- end
7
-
8
- should "Report nil for a document that doesn't include a field" do
9
- doc = SolrInputDocument.new
10
- assert_equal nil, doc[:notinthere]
11
- end
12
-
13
- should "Return single and multiple values in arrays" do
14
- doc = SolrInputDocument.new
15
- doc << [:id, 1]
16
- assert_equal [1], doc[:id]
17
- doc << [:id, 2]
18
- assert_equal [1,2], doc[:id]
19
- end
20
-
21
- should "Add items in hash via merge!" do
22
- doc = SolrInputDocument.new
23
- doc << [:id, 1]
24
- h = {:id => 2, :name => 'Bill'}
25
- doc.merge! h
26
- assert_equal [1,2], doc[:id]
27
- assert_equal ['Bill'], doc[:name]
28
- end
29
-
30
- should "Allow additive_merge! as well" do
31
- doc = SolrInputDocument.new
32
- doc << [:id, 1]
33
- h = {:id => 2, :name => 'Bill'}
34
- doc.additive_merge! h
35
- assert_equal [1,2], doc[:id]
36
- assert_equal ['Bill'], doc[:name]
37
-
38
- end
39
-
40
- should "Destroy existing items via []=" do
41
- doc = SolrInputDocument.new
42
- doc[:id] = 1
43
- assert_equal [1], doc[:id]
44
- doc[:id] = 2
45
- assert_equal [2], doc[:id]
46
- end
47
-
48
-
49
- end