mwmitchell-rsolr 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +3 -0
- data/lib/rsolr/message/builders/builder.rb +85 -0
- data/lib/rsolr/message/builders/libxml.rb +59 -0
- data/lib/rsolr/message/builders.rb +6 -0
- data/lib/rsolr/message.rb +17 -37
- data/rsolr.gemspec +5 -2
- data/test/message_test.rb +49 -20
- metadata +5 -2
data/CHANGES.txt
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
class RSolr::Message::Builders::Builder
|
4
|
+
|
5
|
+
# shortcut method -> xml = RSolr::Message.xml
|
6
|
+
def xml
|
7
|
+
::Builder::XmlMarkup.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# generates "add" xml for updating solr
|
11
|
+
# "data" can be a hash or an array of hashes.
|
12
|
+
# - each hash should be a simple key=>value pair representing a solr doc.
|
13
|
+
# If a value is an array, multiple fields will be created.
|
14
|
+
#
|
15
|
+
# "add_attrs" can be a hash for setting the add xml element attributes.
|
16
|
+
#
|
17
|
+
# This method can also accept a block.
|
18
|
+
# The value yielded to the block is a Message::Document; for each solr doc in "data".
|
19
|
+
# You can set xml element attributes for each "doc" element or individual "field" elements.
|
20
|
+
#
|
21
|
+
# For example:
|
22
|
+
#
|
23
|
+
# solr.add({:id=>1, :nickname=>'Tim'}, {:boost=>5.0, :commitWithin=>1.0}) do |doc_msg|
|
24
|
+
# doc_msg.attrs[:boost] = 10.00 # boost the document
|
25
|
+
# nickname = doc_msg.field_by_name(:nickname)
|
26
|
+
# nickname.attrs[:boost] = 20 if nickname.value=='Tim' # boost a field
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# would result in an add element having the attributes boost="10.0"
|
30
|
+
# and a commitWithin="1.0".
|
31
|
+
# Each doc element would have a boost="10.0".
|
32
|
+
# The "nickname" field would have a boost="20.0"
|
33
|
+
# if the doc had a "nickname" field with the value of "Tim".
|
34
|
+
#
|
35
|
+
def add(documents, add_attrs={})
|
36
|
+
xml.add(add_attrs) do |add_node|
|
37
|
+
documents.each do |doc|
|
38
|
+
# create doc, passing in fields
|
39
|
+
add_node.doc(doc.attrs) do |doc_node|
|
40
|
+
doc.fields.each do |field_obj|
|
41
|
+
doc_node.field(field_obj.value, field_obj.attrs)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# generates a <commit/> message
|
49
|
+
def commit(opts={})
|
50
|
+
xml.commit(opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
# generates a <optimize/> message
|
54
|
+
def optimize(opts={})
|
55
|
+
xml.optimize(opts)
|
56
|
+
end
|
57
|
+
|
58
|
+
# generates a <rollback/> message
|
59
|
+
def rollback
|
60
|
+
xml.rollback
|
61
|
+
end
|
62
|
+
|
63
|
+
# generates a <delete><id>ID</id></delete> message
|
64
|
+
# "ids" can be a single value or array of values
|
65
|
+
def delete_by_id(ids)
|
66
|
+
ids = [ids] unless ids.is_a?(Array)
|
67
|
+
xml.delete do |xml|
|
68
|
+
ids.each do |id|
|
69
|
+
xml.id(id)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# generates a <delete><query>ID</query></delete> message
|
75
|
+
# "queries" can be a single value or an array of values
|
76
|
+
def delete_by_query(queries)
|
77
|
+
queries = [queries] unless queries.is_a?(Array)
|
78
|
+
xml.delete do |xml|
|
79
|
+
queries.each do |query|
|
80
|
+
xml.query(query)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'libxml'
|
2
|
+
|
3
|
+
class RSolr::Message::Builders::Libxml
|
4
|
+
|
5
|
+
def add(documents, attributes = {})
|
6
|
+
add_node = new_node('add', attributes)
|
7
|
+
for document in documents
|
8
|
+
add_node << doc_node = new_node('doc', document.attrs)
|
9
|
+
for field in document.fields
|
10
|
+
doc_node << field_node = new_node('field', field.attrs)
|
11
|
+
field_node << field.value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
add_node.to_s(:indent => false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete_by_id(ids)
|
18
|
+
delete = new_node('delete')
|
19
|
+
for id in Array(ids)
|
20
|
+
id_node = new_node('id')
|
21
|
+
id_node << id
|
22
|
+
delete << id_node
|
23
|
+
end
|
24
|
+
delete.to_s(:indent => false)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_by_query(queries)
|
28
|
+
delete = new_node('delete')
|
29
|
+
for query in Array(queries)
|
30
|
+
query_node = new_node('query')
|
31
|
+
query_node << query
|
32
|
+
delete << query_node
|
33
|
+
end
|
34
|
+
delete.to_s(:indent => false)
|
35
|
+
end
|
36
|
+
|
37
|
+
def optimize(opts)
|
38
|
+
new_node('optimize', opts).to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def rollback
|
42
|
+
new_node('rollback').to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
def commit(opts = {})
|
46
|
+
new_node('commit', opts).to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def new_node(name, opts = {})
|
52
|
+
node = LibXML::XML::Node.new(name)
|
53
|
+
opts.each_pair do |attr, value|
|
54
|
+
node[attr.to_s] = value.to_s
|
55
|
+
end
|
56
|
+
node
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/rsolr/message.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
# http://builder.rubyforge.org/
|
2
|
-
require 'rubygems'
|
3
|
-
require 'builder'
|
4
|
-
|
5
1
|
# The Solr::Message class is the XML generation module for sending updates to Solr.
|
6
2
|
|
7
3
|
class RSolr::Message
|
8
4
|
|
5
|
+
autoload :Builders, 'rsolr/message/builders'
|
6
|
+
|
9
7
|
# A class that represents a "doc" xml element for a solr update
|
10
8
|
class Document
|
11
9
|
|
@@ -77,10 +75,10 @@ class RSolr::Message
|
|
77
75
|
end
|
78
76
|
|
79
77
|
class << self
|
80
|
-
|
81
|
-
|
82
|
-
def
|
83
|
-
::Builder
|
78
|
+
attr_writer :builder
|
79
|
+
|
80
|
+
def builder
|
81
|
+
@builder ||= Builders::Builder.new
|
84
82
|
end
|
85
83
|
|
86
84
|
# generates "add" xml for updating solr
|
@@ -108,59 +106,41 @@ class RSolr::Message
|
|
108
106
|
# The "nickname" field would have a boost="20.0"
|
109
107
|
# if the doc had a "nickname" field with the value of "Tim".
|
110
108
|
#
|
111
|
-
def add(data, add_attrs={}
|
109
|
+
def add(data, add_attrs={})
|
112
110
|
data = [data] unless data.is_a?(Array)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
yield doc if block_given?
|
118
|
-
add_node.doc(doc.attrs) do |doc_node|
|
119
|
-
doc.fields.each do |field_obj|
|
120
|
-
doc_node.field(field_obj.value, field_obj.attrs)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
111
|
+
documents = data.map do |doc|
|
112
|
+
doc = Document.new(doc) if doc.respond_to?(:each_pair)
|
113
|
+
yield doc if block_given?
|
114
|
+
doc
|
124
115
|
end
|
116
|
+
builder.add(documents, add_attrs)
|
125
117
|
end
|
126
118
|
|
127
119
|
# generates a <commit/> message
|
128
120
|
def commit(opts={})
|
129
|
-
|
121
|
+
builder.commit(opts)
|
130
122
|
end
|
131
123
|
|
132
124
|
# generates a <optimize/> message
|
133
125
|
def optimize(opts={})
|
134
|
-
|
126
|
+
builder.optimize(opts)
|
135
127
|
end
|
136
128
|
|
137
129
|
# generates a <rollback/> message
|
138
130
|
def rollback
|
139
|
-
|
131
|
+
builder.rollback
|
140
132
|
end
|
141
133
|
|
142
134
|
# generates a <delete><id>ID</id></delete> message
|
143
135
|
# "ids" can be a single value or array of values
|
144
136
|
def delete_by_id(ids)
|
145
|
-
|
146
|
-
xml.delete do |xml|
|
147
|
-
ids.each do |id|
|
148
|
-
xml.id(id)
|
149
|
-
end
|
150
|
-
end
|
137
|
+
builder.delete_by_id(ids)
|
151
138
|
end
|
152
139
|
|
153
140
|
# generates a <delete><query>ID</query></delete> message
|
154
141
|
# "queries" can be a single value or an array of values
|
155
142
|
def delete_by_query(queries)
|
156
|
-
|
157
|
-
xml.delete do |xml|
|
158
|
-
queries.each do |query|
|
159
|
-
xml.query(query)
|
160
|
-
end
|
161
|
-
end
|
143
|
+
builder.delete_by_query(queries)
|
162
144
|
end
|
163
|
-
|
164
145
|
end
|
165
|
-
|
166
146
|
end
|
data/rsolr.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rsolr"
|
3
|
-
s.version = "0.9.
|
4
|
-
s.date = "2009-07-
|
3
|
+
s.version = "0.9.1"
|
4
|
+
s.date = "2009-07-22"
|
5
5
|
s.summary = "A Ruby client for Apache Solr"
|
6
6
|
s.email = "goodieboy@gmail.com"
|
7
7
|
s.homepage = "http://github.com/mwmitchell/rsolr"
|
@@ -20,6 +20,9 @@ Gem::Specification.new do |s|
|
|
20
20
|
"lib/rsolr/http_client/adapter/net_http.rb",
|
21
21
|
"lib/rsolr/http_client/adapter.rb",
|
22
22
|
"lib/rsolr/http_client.rb",
|
23
|
+
"lib/rsolr/message/builders/builder.rb",
|
24
|
+
"lib/rsolr/message/builders/libxml.rb",
|
25
|
+
"lib/rsolr/message/builders.rb",
|
23
26
|
"lib/rsolr/message.rb",
|
24
27
|
"LICENSE",
|
25
28
|
"Rakefile",
|
data/test/message_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
|
4
|
+
module MessageTestMethods
|
5
5
|
|
6
6
|
# call all of the simple methods...
|
7
7
|
# make sure the xml string is valid
|
@@ -13,7 +13,7 @@ class MessageTest < RSolrBaseTest
|
|
13
13
|
assert_equal String, result.class
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def test_add_yields_doc_objects_if_block_given
|
18
18
|
documents = [{:id=>1, :name=>'sam', :cat=>['cat 1', 'cat 2']}]
|
19
19
|
add_attrs = {:boost=>200.00}
|
@@ -36,31 +36,31 @@ class MessageTest < RSolrBaseTest
|
|
36
36
|
assert result =~ %r(boost="10")
|
37
37
|
assert result =~ %r(<field name="id">1</field>)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def test_delete_by_id
|
41
41
|
result = RSolr::Message.delete_by_id(10)
|
42
42
|
assert_equal String, result.class
|
43
43
|
assert_equal '<delete><id>10</id></delete>', result.to_s
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def test_delete_by_multiple_ids
|
47
47
|
result = RSolr::Message.delete_by_id([1, 2, 3])
|
48
48
|
assert_equal String, result.class
|
49
49
|
assert_equal '<delete><id>1</id><id>2</id><id>3</id></delete>', result.to_s
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def test_delete_by_query
|
53
|
-
result = RSolr::Message.
|
53
|
+
result = RSolr::Message.delete_by_query('status:"LOST"')
|
54
54
|
assert_equal String, result.class
|
55
|
-
assert_equal '<delete><
|
55
|
+
assert_equal '<delete><query>status:"LOST"</query></delete>', result.to_s
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def test_delete_by_multiple_queries
|
59
|
-
result = RSolr::Message.
|
59
|
+
result = RSolr::Message.delete_by_query(['status:"LOST"', 'quantity:0'])
|
60
60
|
assert_equal String, result.class
|
61
|
-
assert_equal '<delete><
|
61
|
+
assert_equal '<delete><query>status:"LOST"</query><query>quantity:0</query></delete>', result.to_s
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
# add a single hash ("doc")
|
65
65
|
def test_add_hash
|
66
66
|
data = {
|
@@ -70,7 +70,7 @@ class MessageTest < RSolrBaseTest
|
|
70
70
|
assert RSolr::Message.add(data).to_s =~ /<field name="name">matt<\/field>/
|
71
71
|
assert RSolr::Message.add(data).to_s =~ /<field name="id">1<\/field>/
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
# add an array of hashes
|
75
75
|
def test_add_array
|
76
76
|
data = [
|
@@ -83,35 +83,35 @@ class MessageTest < RSolrBaseTest
|
|
83
83
|
:name=>'sam'
|
84
84
|
}
|
85
85
|
]
|
86
|
-
|
86
|
+
|
87
87
|
message = RSolr::Message.add(data)
|
88
88
|
expected = '<add><doc><field name="id">1</field><field name="name">matt</field></doc><doc><field name="id">2</field><field name="name">sam</field></doc></add>'
|
89
|
-
|
89
|
+
|
90
90
|
assert message.to_s=~/<field name="name">matt<\/field>/
|
91
91
|
assert message.to_s=~/<field name="name">sam<\/field>/
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
# multiValue field support test, thanks to Fouad Mardini!
|
95
95
|
def test_add_multi_valued_field
|
96
96
|
data = {
|
97
97
|
:id => 1,
|
98
98
|
:name => ['matt1', 'matt2']
|
99
99
|
}
|
100
|
-
|
100
|
+
|
101
101
|
result = RSolr::Message.add(data)
|
102
|
-
|
102
|
+
|
103
103
|
assert result.to_s =~ /<field name="name">matt1<\/field>/
|
104
104
|
assert result.to_s =~ /<field name="name">matt2<\/field>/
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
def test_add_single_document
|
108
108
|
document = RSolr::Message::Document.new
|
109
109
|
document.add_field('id', 1)
|
110
110
|
document.add_field('name', 'matt', :boost => 2.0)
|
111
111
|
result = RSolr::Message.add(document)
|
112
|
-
|
112
|
+
|
113
113
|
assert result.to_s =~ /<field name="id">1<\/field>/
|
114
|
-
|
114
|
+
|
115
115
|
# depending on which ruby version, the attributes can be out of place
|
116
116
|
# so we need to test both... there's gotta be a better way to do this?
|
117
117
|
assert(
|
@@ -132,4 +132,33 @@ class MessageTest < RSolrBaseTest
|
|
132
132
|
assert result.to_s =~ /<field name="name">matt1<\/field>/
|
133
133
|
assert result.to_s =~ /<field name="name">matt2<\/field>/
|
134
134
|
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
#####
|
139
|
+
|
140
|
+
unless defined?(JRUBY_VERSION)
|
141
|
+
class LibxmlMessageTest < RSolrBaseTest
|
142
|
+
|
143
|
+
include MessageTestMethods
|
144
|
+
|
145
|
+
def setup
|
146
|
+
RSolr::Message.builder = RSolr::Message::Builders::Libxml.new
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
135
150
|
end
|
151
|
+
|
152
|
+
|
153
|
+
#####
|
154
|
+
|
155
|
+
class BuilderMessageTest < RSolrBaseTest
|
156
|
+
|
157
|
+
include MessageTestMethods
|
158
|
+
|
159
|
+
def setup
|
160
|
+
# RSolr::Message::Builders::Libxml.new
|
161
|
+
RSolr::Message.builder = RSolr::Message::Builders::Builder.new
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mwmitchell-rsolr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Mitchell
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -45,6 +45,9 @@ files:
|
|
45
45
|
- lib/rsolr/http_client/adapter/net_http.rb
|
46
46
|
- lib/rsolr/http_client/adapter.rb
|
47
47
|
- lib/rsolr/http_client.rb
|
48
|
+
- lib/rsolr/message/builders/builder.rb
|
49
|
+
- lib/rsolr/message/builders/libxml.rb
|
50
|
+
- lib/rsolr/message/builders.rb
|
48
51
|
- lib/rsolr/message.rb
|
49
52
|
- LICENSE
|
50
53
|
- Rakefile
|