rsolr 0.9.7.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +21 -0
- data/README.rdoc +39 -5
- data/lib/rsolr/client.rb +38 -15
- data/lib/rsolr/connection/direct.rb +7 -26
- data/lib/rsolr/connection/net_http.rb +12 -3
- data/lib/rsolr/pagination.rb +59 -0
- data/lib/rsolr.rb +26 -27
- data/rsolr.gemspec +29 -0
- metadata +7 -15
- data/Rakefile +0 -14
- data/examples/direct.rb +0 -29
- data/examples/http.rb +0 -24
- data/test/connection/direct_test.rb +0 -37
- data/test/connection/net_http_test.rb +0 -29
- data/test/connection/test_methods.rb +0 -97
- data/test/connection/utils_test.rb +0 -83
- data/test/helper.rb +0 -61
- data/test/message_test.rb +0 -140
- data/test/rsolr_test.rb +0 -21
data/CHANGES.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
0.9.10 - November 13, 2009
|
2
|
+
Changed RSolr.connect to return Http connection only:
|
3
|
+
RSolr.connect :url=>'xxx'
|
4
|
+
Added RSolr.direct_connect to handle the creation of SolrDirectConnections
|
5
|
+
rsolr = RSolr.direct_connect :home_dir=>''
|
6
|
+
|
7
|
+
# can also use a block so the connection will get closed automatically:
|
8
|
+
RSolr.direct_connect :home_dir=>'' do |rsolr|
|
9
|
+
# query...
|
10
|
+
end
|
11
|
+
Added paginate method to RSolr::Client
|
12
|
+
- This method requires 2 new arguments: current page and per page:
|
13
|
+
solr.paginate 1, 10, :q=>''
|
14
|
+
- handler paths can be set:
|
15
|
+
solr.paginate 1, 10, '/music', :q=>''
|
16
|
+
- handler paths can also be set by method names:
|
17
|
+
solr.paginate_music 1, 10
|
18
|
+
Added required java libs to RSolr gem
|
19
|
+
Removed :dist_dir option from Direct connection options -- you gotta load your own java libs. See examples/direct.rb
|
20
|
+
Updated specs
|
21
|
+
|
1
22
|
0.9.7.2 - November 6, 2009
|
2
23
|
fixed gem spec, added client.rb
|
3
24
|
|
data/README.rdoc
CHANGED
@@ -30,12 +30,25 @@ A Ruby client for Apache Solr. RSolr has been developed to be simple and extenda
|
|
30
30
|
|
31
31
|
To use a DirectSolrConnection (no http) in JRuby:
|
32
32
|
|
33
|
-
solr
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
# "apache-solr" should be a path to a solr build.
|
34
|
+
Dir['apache-solr/dist/*.jar'].each{|jar|require jar}
|
35
|
+
Dir['apache-solr/lib/*.jar'].each{|jar|require jar}
|
36
|
+
|
37
|
+
opts = {:home_dir=>'/path/to/solr/home'}
|
38
|
+
|
39
|
+
# note: you'll have to close the direct connection yourself unless using a block.
|
40
|
+
solr = RSolr.direct_connect(opts)
|
41
|
+
solr.select :q=>'*:*'
|
42
|
+
solr.connection.close
|
43
|
+
|
44
|
+
# OR using a block for automatic connection closing:
|
45
|
+
RSolr.direct_connect opts do |solr|
|
46
|
+
solr.select :q=>'*:*'
|
47
|
+
end
|
48
|
+
|
49
|
+
In general, the direct connection is less than ideal in most applications. You'll be missing out on Http caching, and it'll be impossible to do distributed searches. The direct connection could possibly come in handy though, for quickly indexing large numbers of documents.
|
37
50
|
|
38
|
-
For more information about
|
51
|
+
For more information about DirectSolrConnection, see the {API}[http://lucene.apache.org/solr/api/org/apache/solr/servlet/DirectSolrConnection.html].
|
39
52
|
|
40
53
|
|
41
54
|
== Querying
|
@@ -61,6 +74,27 @@ A shortcut for the above example:
|
|
61
74
|
response = solr.documents :q=>'test'
|
62
75
|
|
63
76
|
|
77
|
+
===Doc Pagination
|
78
|
+
RSolr is compatible with WillPaginate. To use pagination, call the "paginate" method:
|
79
|
+
response = solr.paginate current_page, per_page, :q=>'*:*'
|
80
|
+
|
81
|
+
You can also set a handler path:
|
82
|
+
response = solr.paginate current_page, per_page, '/music', :q=>'*:*'
|
83
|
+
|
84
|
+
Handler paths can also be set using a paginate_* method call like so:
|
85
|
+
response = solr.paginate_music current_page, per_page, :q=>'testing'
|
86
|
+
|
87
|
+
====Pagination Responses
|
88
|
+
The response['docs'] array from a paginate method has the following methods:
|
89
|
+
start, per_page, total, current_page, total_pages, previous_page, next_page, has_next?, has_previous?
|
90
|
+
|
91
|
+
For example:
|
92
|
+
result = solr.paginate 1, 2, :q=>'*:*'
|
93
|
+
result['response']['docs'].has_next?
|
94
|
+
|
95
|
+
To use with WillPaginate:
|
96
|
+
<%= will_paginate result['response']['docs'] %>
|
97
|
+
|
64
98
|
== Updating Solr
|
65
99
|
Updating can be done using native Ruby structures. Hashes are used for single documents and arrays are used for a collection of documents (hashes). These structures get turned into simple XML "messages". Raw XML strings can also be used.
|
66
100
|
|
data/lib/rsolr/client.rb
CHANGED
@@ -1,18 +1,41 @@
|
|
1
1
|
class RSolr::Client
|
2
2
|
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :connection
|
4
4
|
|
5
|
-
# "
|
5
|
+
# "connection" is instance of:
|
6
6
|
# RSolr::Adapter::HTTP
|
7
7
|
# RSolr::Adapter::Direct (jRuby only)
|
8
8
|
# or any other class that uses the connection "interface"
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(connection)
|
10
|
+
@connection = connection
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Send a request to a request handler using the method name.
|
14
|
+
# Also proxies to the #paginate method if the method starts with "paginate_"
|
14
15
|
def method_missing(method_name, *args, &blk)
|
15
|
-
|
16
|
+
handler = method_name.to_s
|
17
|
+
if handler =~ /^paginate_/
|
18
|
+
handler = handler.sub(/^paginate_/, '')
|
19
|
+
page, per_page = args[0..1]
|
20
|
+
paginate(page, per_page, "/#{handler}", *args[2..-1], &blk)
|
21
|
+
else
|
22
|
+
request("/#{handler}", *args, &blk)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Accepts a page/per-page value for paginating docs
|
27
|
+
# Example:
|
28
|
+
# solr.paginate 1, 10, :q=>'blah'
|
29
|
+
def paginate page, per_page, *request_args
|
30
|
+
if request_args.size == 2
|
31
|
+
params = request_args.last
|
32
|
+
elsif request_args.last.is_a? Hash
|
33
|
+
params = request_args.last
|
34
|
+
else
|
35
|
+
params = request_args.push({}).last
|
36
|
+
end
|
37
|
+
params[:start], params[:rows] = RSolr::Pagination.page_and_per_page_to_start_and_rows page, per_page
|
38
|
+
self.request(*request_args).extend RSolr::Pagination
|
16
39
|
end
|
17
40
|
|
18
41
|
# sends data to the update handler
|
@@ -30,7 +53,7 @@ class RSolr::Client
|
|
30
53
|
#
|
31
54
|
#
|
32
55
|
def request(path, params={}, *extra)
|
33
|
-
response = @
|
56
|
+
response = @connection.request(path, map_params(params), *extra)
|
34
57
|
adapt_response(response)
|
35
58
|
end
|
36
59
|
|
@@ -89,24 +112,24 @@ class RSolr::Client
|
|
89
112
|
{:wt=>:ruby}.merge(params)
|
90
113
|
end
|
91
114
|
|
92
|
-
# "
|
115
|
+
# "connection_response" must be a hash with the following keys:
|
93
116
|
# :params - a sub hash of standard solr params
|
94
117
|
# : body - the raw response body from the solr server
|
95
118
|
# This method will evaluate the :body value if the params[:wt] == :ruby
|
96
119
|
# otherwise, the body is returned
|
97
|
-
# The return object has a special method attached called #
|
98
|
-
# This method gives you access to the original response from the
|
120
|
+
# The return object has a special method attached called #connection_response
|
121
|
+
# This method gives you access to the original response from the connection,
|
99
122
|
# so you can access things like the actual :url sent to solr,
|
100
123
|
# the raw :body, original :params and original :data
|
101
|
-
def adapt_response(
|
102
|
-
data =
|
124
|
+
def adapt_response(connection_response)
|
125
|
+
data = connection_response[:body]
|
103
126
|
# if the wt is :ruby, evaluate the ruby string response
|
104
|
-
if
|
127
|
+
if connection_response[:params][:wt] == :ruby
|
105
128
|
data = Kernel.eval(data)
|
106
129
|
end
|
107
|
-
# attach a method called #
|
130
|
+
# attach a method called #connection_response that returns the original connection response value
|
108
131
|
def data.raw; @raw end
|
109
|
-
data.send(:instance_variable_set, '@raw',
|
132
|
+
data.send(:instance_variable_set, '@raw', connection_response)
|
110
133
|
data
|
111
134
|
end
|
112
135
|
|
@@ -15,13 +15,9 @@ class RSolr::Connection::Direct
|
|
15
15
|
# if opts is NOT an instance of org.apache.solr.servlet.DirectSolrConnection
|
16
16
|
# then...
|
17
17
|
# required: opts[:home_dir] is absolute path to solr home (the directory with "data", "config" etc.)
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# :jar_paths => ['array of directories containing the solr lib/jars']
|
22
|
-
# OTHER OPTS:
|
23
|
-
# :select_path => 'the/select/handler'
|
24
|
-
# :update_path => 'the/update/handler'
|
18
|
+
#
|
19
|
+
# You can load your own solr java libs by setting :autoload_jars to false.
|
20
|
+
# When set to true (default), RSolr loads its own set of solr java libs.
|
25
21
|
def initialize(opts, &block)
|
26
22
|
if defined?(Java::OrgApacheSolrCore::SolrCore) and opts.is_a?(Java::OrgApacheSolrCore::SolrCore)
|
27
23
|
@connection = org.apache.solr.servlet.DirectSolrConnection.new(opts)
|
@@ -29,19 +25,13 @@ class RSolr::Connection::Direct
|
|
29
25
|
@connection = opts
|
30
26
|
else
|
31
27
|
opts[:data_dir] ||= File.join(opts[:home_dir].to_s, 'data')
|
32
|
-
if opts[:dist_dir] and ! opts[:jar_paths]
|
33
|
-
# add the standard lib and dist directories to the :jar_paths
|
34
|
-
opts[:jar_paths] = [File.join(opts[:dist_dir], 'lib'), File.join(opts[:dist_dir], 'dist')]
|
35
|
-
end
|
36
28
|
@opts = opts
|
37
29
|
end
|
38
30
|
end
|
39
31
|
|
40
|
-
# loads/imports the java dependencies
|
41
32
|
# sets the @connection instance variable if it has not yet been set
|
42
33
|
def connection
|
43
34
|
@connection ||= (
|
44
|
-
require_jars(@opts[:jar_paths]) if @opts[:jar_paths]
|
45
35
|
org.apache.solr.servlet.DirectSolrConnection.new(opts[:home_dir], @opts[:data_dir], nil)
|
46
36
|
)
|
47
37
|
end
|
@@ -65,24 +55,15 @@ class RSolr::Connection::Direct
|
|
65
55
|
raise RSolr::RequestError.new($!.message)
|
66
56
|
end
|
67
57
|
{
|
68
|
-
:
|
58
|
+
:status_code => 200,
|
69
59
|
:url=>url,
|
60
|
+
:body=>body,
|
70
61
|
:path=>path,
|
71
62
|
:params=>params,
|
72
63
|
:data=>data,
|
64
|
+
:headers => {},
|
65
|
+
:message => ''
|
73
66
|
}
|
74
67
|
end
|
75
68
|
|
76
|
-
protected
|
77
|
-
|
78
|
-
# require the jar files
|
79
|
-
def require_jars(paths)
|
80
|
-
paths = [paths] unless paths.is_a?(Array)
|
81
|
-
paths.each do |path|
|
82
|
-
raise "Invalid jar path: #{path}" unless File.exists?(path)
|
83
|
-
jar_pattern = File.join(path,"**", "*.jar")
|
84
|
-
Dir[jar_pattern].each {|jar_file| require jar_file }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
69
|
end
|
@@ -34,7 +34,7 @@ class RSolr::Connection::NetHttp
|
|
34
34
|
http_context = self.get(path, params)
|
35
35
|
end
|
36
36
|
end
|
37
|
-
raise RSolr::RequestError.new(http_context[:
|
37
|
+
raise RSolr::RequestError.new("Solr Response: #{http_context[:message]}") unless http_context[:status_code] == 200
|
38
38
|
http_context
|
39
39
|
end
|
40
40
|
|
@@ -63,14 +63,23 @@ class RSolr::Connection::NetHttp
|
|
63
63
|
{
|
64
64
|
:status_code=>net_http_response.code.to_i,
|
65
65
|
:url=>full_url,
|
66
|
-
:body=>net_http_response.body,
|
66
|
+
:body=> encode_utf8(net_http_response.body),
|
67
67
|
:path=>path,
|
68
68
|
:params=>params,
|
69
69
|
:data=>data,
|
70
|
-
:headers=>headers
|
70
|
+
:headers=>headers,
|
71
|
+
:message => net_http_response.message
|
71
72
|
}
|
72
73
|
end
|
73
74
|
|
75
|
+
# encodes the string as utf-8 in Ruby 1.9
|
76
|
+
# returns the unaltered string in Ruby 1.8
|
77
|
+
def encode_utf8 string
|
78
|
+
(string.respond_to?(:force_encoding) and string.respond_to?(:encoding)) ?
|
79
|
+
string.force_encoding(Encoding::UTF_8) : string
|
80
|
+
end
|
81
|
+
|
82
|
+
# accepts a path/string and optional hash of query params
|
74
83
|
def build_url path, params={}
|
75
84
|
full_path = @uri.path + path
|
76
85
|
super full_path, params, @uri.query
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RSolr::Pagination
|
2
|
+
|
3
|
+
def self.extended solr_response
|
4
|
+
d = solr_response['response']['docs']
|
5
|
+
d.extend Paginator
|
6
|
+
d.per_page = solr_response['responseHeader']['params']['rows'].to_s.to_i
|
7
|
+
d.start = solr_response['response']['start'].to_s.to_i
|
8
|
+
d.total = solr_response['response']['numFound'].to_s.to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.page_and_per_page_to_start_and_rows page, per_page
|
12
|
+
rows = per_page.to_s.to_i
|
13
|
+
page = page.to_s.to_i-1
|
14
|
+
page = page < 1 ? 0 : page
|
15
|
+
start = page * rows
|
16
|
+
[start, rows]
|
17
|
+
end
|
18
|
+
|
19
|
+
module Paginator
|
20
|
+
|
21
|
+
attr_accessor :start, :per_page, :total
|
22
|
+
|
23
|
+
# Returns the current page calculated from 'rows' and 'start'
|
24
|
+
# WillPaginate hook
|
25
|
+
def current_page
|
26
|
+
return 1 if start < 1
|
27
|
+
per_page_normalized = per_page < 1 ? 1 : per_page
|
28
|
+
@current_page ||= (start / per_page_normalized).ceil + 1
|
29
|
+
end
|
30
|
+
|
31
|
+
# Calcuates the total pages from 'numFound' and 'rows'
|
32
|
+
# WillPaginate hook
|
33
|
+
def total_pages
|
34
|
+
@total_pages ||= per_page > 0 ? (total / per_page.to_f).ceil : 1
|
35
|
+
end
|
36
|
+
|
37
|
+
# returns the previous page number or 1
|
38
|
+
# WillPaginate hook
|
39
|
+
def previous_page
|
40
|
+
@previous_page ||= (current_page > 1) ? current_page - 1 : 1
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns the next page number or the last
|
44
|
+
# WillPaginate hook
|
45
|
+
def next_page
|
46
|
+
@next_page ||= (current_page == total_pages) ? total_pages : current_page+1
|
47
|
+
end
|
48
|
+
|
49
|
+
def has_next?
|
50
|
+
current_page < total_pages
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_previous?
|
54
|
+
current_page > 1
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/lib/rsolr.rb
CHANGED
@@ -8,38 +8,37 @@ require 'xout'
|
|
8
8
|
|
9
9
|
module RSolr
|
10
10
|
|
11
|
-
VERSION = '0.
|
11
|
+
VERSION = '0.10.0'
|
12
12
|
|
13
13
|
autoload :Message, 'rsolr/message'
|
14
14
|
autoload :Client, 'rsolr/client'
|
15
15
|
autoload :Connection, 'rsolr/connection'
|
16
|
+
autoload :Pagination, 'rsolr/pagination'
|
16
17
|
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
adapter = adapter_class.new(*opts)
|
42
|
-
RSolr::Client.new(adapter)
|
18
|
+
# returns path to this file directory
|
19
|
+
def self.dir
|
20
|
+
File.expand_path(File.dirname(__FILE__))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Http connection. Example:
|
24
|
+
# RSolr.connect
|
25
|
+
# RSolr.connect 'http://solr.web100.org'
|
26
|
+
def self.connect *args
|
27
|
+
Client.new(Connection::NetHttp.new(*args))
|
28
|
+
end
|
29
|
+
|
30
|
+
# DirectSolrConnection (jruby only). Example:
|
31
|
+
# RSolr.direct_connect 'path/to/solr/distribution'
|
32
|
+
# RSolr.direct_connect :dist_dir=>'path/to/solr/distribution', :home_dir=>'/path/to/solrhome'
|
33
|
+
# RSolr.direct_connect opts do |rsolr|
|
34
|
+
# ###
|
35
|
+
# end
|
36
|
+
# Note:
|
37
|
+
# if a block is used, the client is yielded and the solr core will be closed for you.
|
38
|
+
# if a block is NOT used, the the client is returned and the core is NOT closed.
|
39
|
+
def self.direct_connect *args, &blk
|
40
|
+
rsolr = Client.new(Connection::Direct.new(*args))
|
41
|
+
block_given? ? (yield rsolr and rsolr.connection.close) : rsolr
|
43
42
|
end
|
44
43
|
|
45
44
|
# A module that contains string related methods
|
data/rsolr.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "rsolr"
|
3
|
+
s.version = "0.10.0"
|
4
|
+
s.date = "2009-11-13"
|
5
|
+
s.summary = "A Ruby client for Apache Solr"
|
6
|
+
s.email = "goodieboy@gmail.com"
|
7
|
+
s.homepage = "http://github.com/mwmitchell/rsolr"
|
8
|
+
s.description = "RSolr is a Ruby gem for working with Apache Solr!"
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.authors = ["Matt Mitchell"]
|
11
|
+
|
12
|
+
s.files = [
|
13
|
+
"CHANGES.txt",
|
14
|
+
"lib/rsolr/client.rb",
|
15
|
+
"lib/rsolr/connection/direct.rb",
|
16
|
+
"lib/rsolr/connection/net_http.rb",
|
17
|
+
"lib/rsolr/connection.rb",
|
18
|
+
"lib/rsolr/message.rb",
|
19
|
+
"lib/rsolr/pagination.rb",
|
20
|
+
"lib/rsolr.rb",
|
21
|
+
"lib/xout.rb",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"rsolr.gemspec"
|
25
|
+
]
|
26
|
+
|
27
|
+
#s.rdoc_options = ["--main", "README.rdoc"]
|
28
|
+
s.extra_rdoc_files = %w(LICENSE README.rdoc CHANGES.txt)
|
29
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsolr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
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-11-
|
12
|
+
date: 2009-11-13 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -21,23 +21,21 @@ extensions: []
|
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- LICENSE
|
24
|
-
- Rakefile
|
25
24
|
- README.rdoc
|
26
25
|
- CHANGES.txt
|
27
26
|
files:
|
28
|
-
-
|
29
|
-
- examples/http.rb
|
27
|
+
- CHANGES.txt
|
30
28
|
- lib/rsolr/client.rb
|
31
29
|
- lib/rsolr/connection/direct.rb
|
32
30
|
- lib/rsolr/connection/net_http.rb
|
33
31
|
- lib/rsolr/connection.rb
|
34
32
|
- lib/rsolr/message.rb
|
33
|
+
- lib/rsolr/pagination.rb
|
35
34
|
- lib/rsolr.rb
|
36
35
|
- lib/xout.rb
|
37
36
|
- LICENSE
|
38
|
-
- Rakefile
|
39
37
|
- README.rdoc
|
40
|
-
-
|
38
|
+
- rsolr.gemspec
|
41
39
|
has_rdoc: true
|
42
40
|
homepage: http://github.com/mwmitchell/rsolr
|
43
41
|
licenses: []
|
@@ -66,11 +64,5 @@ rubygems_version: 1.3.5
|
|
66
64
|
signing_key:
|
67
65
|
specification_version: 3
|
68
66
|
summary: A Ruby client for Apache Solr
|
69
|
-
test_files:
|
70
|
-
|
71
|
-
- test/connection/net_http_test.rb
|
72
|
-
- test/connection/test_methods.rb
|
73
|
-
- test/connection/utils_test.rb
|
74
|
-
- test/helper.rb
|
75
|
-
- test/message_test.rb
|
76
|
-
- test/rsolr_test.rb
|
67
|
+
test_files: []
|
68
|
+
|
data/Rakefile
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
require 'rake/gempackagetask'
|
5
|
-
|
6
|
-
ENV['RUBYOPT'] = '-W1'
|
7
|
-
|
8
|
-
task :environment do
|
9
|
-
require File.dirname(__FILE__) + '/lib/rsolr'
|
10
|
-
end
|
11
|
-
|
12
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
13
|
-
|
14
|
-
task :default => ['spec:api']
|
data/examples/direct.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# Must be executed using jruby
|
2
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'rsolr')
|
3
|
-
|
4
|
-
base = File.expand_path( File.dirname(__FILE__) )
|
5
|
-
dist = File.join(base, '..', 'apache-solr')
|
6
|
-
home = File.join(dist, 'example', 'solr')
|
7
|
-
|
8
|
-
solr = RSolr.connect(:direct, :home_dir=>home, :dist_dir=>dist)
|
9
|
-
|
10
|
-
Dir['../apache-solr/example/exampledocs/*.xml'].each do |xml_file|
|
11
|
-
puts "Updating with #{xml_file}"
|
12
|
-
solr.update File.read(xml_file)
|
13
|
-
end
|
14
|
-
|
15
|
-
solr.commit
|
16
|
-
|
17
|
-
puts
|
18
|
-
|
19
|
-
response = solr.select :q=>'ipod', :fq=>'price:[0 TO 50]', :rows=>2, :start=>0
|
20
|
-
|
21
|
-
docs = response['response']['docs']
|
22
|
-
|
23
|
-
docs.each do |doc|
|
24
|
-
puts doc['timestamp']
|
25
|
-
end
|
26
|
-
|
27
|
-
solr.delete_by_query('*:*') and solr.commit
|
28
|
-
|
29
|
-
solr.adapter.close
|
data/examples/http.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'rsolr')
|
2
|
-
|
3
|
-
solr = RSolr.connect
|
4
|
-
|
5
|
-
Dir['../apache-solr/example/exampledocs/*.xml'].each do |xml_file|
|
6
|
-
puts "Updating with #{xml_file}"
|
7
|
-
solr.update File.read(xml_file)
|
8
|
-
end
|
9
|
-
|
10
|
-
solr.commit
|
11
|
-
|
12
|
-
puts
|
13
|
-
|
14
|
-
response = solr.select(:q=>'ipod', :fq=>['price:[0 TO 50]'], :rows=>2, :start=>0)
|
15
|
-
|
16
|
-
puts "URL : #{response.raw[:url]} -> #{response.raw[:status_code]}"
|
17
|
-
|
18
|
-
puts
|
19
|
-
|
20
|
-
response['response']['docs'].each do |doc|
|
21
|
-
puts doc['timestamp']
|
22
|
-
end
|
23
|
-
|
24
|
-
solr.delete_by_query('*:*') and solr.commit
|
@@ -1,37 +0,0 @@
|
|
1
|
-
if defined?(JRUBY_VERSION)
|
2
|
-
|
3
|
-
require 'helper'
|
4
|
-
require 'connection/test_methods'
|
5
|
-
|
6
|
-
class ConnectionDirectTest < RSolrBaseTest
|
7
|
-
|
8
|
-
include ConnectionTestMethods
|
9
|
-
|
10
|
-
attr :dist
|
11
|
-
attr :home
|
12
|
-
|
13
|
-
def setup
|
14
|
-
base = File.expand_path( File.dirname(__FILE__) )
|
15
|
-
@dist = File.join(base, '..', '..', 'solr')
|
16
|
-
@home = File.join(dist, 'example', 'solr')
|
17
|
-
@solr = RSolr.connect(:direct, :home_dir=>@home, :dist_dir=>@dist)
|
18
|
-
@solr.delete_by_query('*:*')
|
19
|
-
@solr.commit
|
20
|
-
end
|
21
|
-
|
22
|
-
def teardown
|
23
|
-
@solr.adapter.close
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_new_connection_with_existing_core
|
27
|
-
Dir["#{@dist}/dist/*.jar"].each { |p| require p }
|
28
|
-
dc = org.apache.solr.servlet.DirectSolrConnection.new(@home, "#{@home}/data", nil)
|
29
|
-
adapter = RSolr::Connection::Direct.new dc
|
30
|
-
s = RSolr::Connection::Base.new(adapter)
|
31
|
-
assert_equal Hash, s.request('/admin/ping').class
|
32
|
-
adapter.close
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
unless defined?(JRUBY_VERSION)
|
2
|
-
|
3
|
-
require 'helper'
|
4
|
-
require 'connection/test_methods'
|
5
|
-
|
6
|
-
class NetHttpTest < RSolrBaseTest
|
7
|
-
|
8
|
-
include ConnectionTestMethods
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@solr = RSolr.connect
|
12
|
-
@solr.delete_by_query('*:*')
|
13
|
-
@solr.commit
|
14
|
-
end
|
15
|
-
|
16
|
-
# http://www.w3.org/TR/html4/interact/forms.html#submit-format
|
17
|
-
|
18
|
-
# due to the way some servers implement their query string parsing,
|
19
|
-
# POST is sometimes needed for large query strings.
|
20
|
-
# This test simply shows that a large q value will not blow up solr.
|
21
|
-
def test_post_for_select
|
22
|
-
big_honkin_q = (['ipod']*1000).join(' OR ')
|
23
|
-
response = @solr.adapter.request '/select', {:q=>big_honkin_q}, :method=>:post
|
24
|
-
assert response
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
# These are all of the test methods used by the various connection + adapter tests
|
2
|
-
# Currently: Direct and HTTP
|
3
|
-
# By sharing these tests, we can make sure the adapters are doing what they're suppossed to
|
4
|
-
# while staying "dry"
|
5
|
-
|
6
|
-
module ConnectionTestMethods
|
7
|
-
|
8
|
-
|
9
|
-
def teardown
|
10
|
-
@solr.delete_by_query('id:[* TO *]')
|
11
|
-
@solr.commit
|
12
|
-
assert_equal 0, @solr.select(:q=>'*:*')['response']['docs'].size
|
13
|
-
end
|
14
|
-
|
15
|
-
# If :wt is NOT :ruby, the format doesn't get converted into a Mash (special Hash; see lib/mash.rb)
|
16
|
-
# Raw ruby can be returned by using :wt=>'ruby', not :ruby
|
17
|
-
def test_raw_response_formats
|
18
|
-
ruby_response = @solr.select(:q=>'*:*', :wt=>'ruby')
|
19
|
-
assert ruby_response.is_a?(String)
|
20
|
-
assert ruby_response =~ %r('wt'=>'ruby')
|
21
|
-
# xml?
|
22
|
-
xml_response = @solr.select(:q=>'*:*', :wt=>'xml')
|
23
|
-
assert xml_response.is_a?(String)
|
24
|
-
assert xml_response =~ %r(<str name="wt">xml</str>)
|
25
|
-
# json?
|
26
|
-
json_response = @solr.select(:q=>'*:*', :wt=>'json')
|
27
|
-
assert json_response.is_a?(String)
|
28
|
-
assert json_response =~ %r("wt":"json")
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_raise_on_invalid_query
|
32
|
-
assert_raise RSolr::RequestError do
|
33
|
-
@solr.select(:q=>'!')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_select_response_docs
|
38
|
-
@solr.add(:id=>1, :price=>1.00, :cat=>['electronics', 'something else'])
|
39
|
-
@solr.commit
|
40
|
-
r = @solr.select(:q=>'*:*')
|
41
|
-
assert r.is_a?(Hash)
|
42
|
-
|
43
|
-
docs = r['response']['docs']
|
44
|
-
assert_equal Array, docs.class
|
45
|
-
first = docs.first
|
46
|
-
|
47
|
-
# test the has? method
|
48
|
-
assert_equal 1.00, first['price']
|
49
|
-
|
50
|
-
assert_equal Array, first['cat'].class
|
51
|
-
assert first['cat'].include?('electronics')
|
52
|
-
assert first['cat'].include?('something else')
|
53
|
-
assert first['cat'].include?('something else')
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_add
|
58
|
-
assert_equal 0, @solr.select(:q=>'*:*')['response']['numFound']
|
59
|
-
update_response = @solr.add({:id=>100})
|
60
|
-
assert update_response.is_a?(Hash)
|
61
|
-
#
|
62
|
-
@solr.commit
|
63
|
-
assert_equal 1, @solr.select(:q=>'*:*')['response']['numFound']
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_delete_by_id
|
67
|
-
@solr.add(:id=>100)
|
68
|
-
@solr.commit
|
69
|
-
total = @solr.select(:q=>'*:*')['response']['numFound']
|
70
|
-
assert_equal 1, total
|
71
|
-
delete_response = @solr.delete_by_id(100)
|
72
|
-
@solr.commit
|
73
|
-
assert delete_response.is_a?(Hash)
|
74
|
-
total = @solr.select(:q=>'*:*')['response']['numFound']
|
75
|
-
assert_equal 0, total
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_delete_by_query
|
79
|
-
@solr.add(:id=>1, :name=>'BLAH BLAH BLAH')
|
80
|
-
@solr.commit
|
81
|
-
assert_equal 1, @solr.select(:q=>'*:*')['response']['numFound']
|
82
|
-
response = @solr.delete_by_query('name:"BLAH BLAH BLAH"')
|
83
|
-
@solr.commit
|
84
|
-
assert response.is_a?(Hash)
|
85
|
-
assert_equal 0, @solr.select(:q=>'*:*')['response']['numFound']
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_admin_luke_index_info
|
89
|
-
response = @solr.request('/admin/luke', :numTerms=>0)
|
90
|
-
assert response.is_a?(Hash)
|
91
|
-
# make sure the ? methods are true/false
|
92
|
-
assert [true, false].include?(response['index']['current'])
|
93
|
-
assert [true, false].include?(response['index']['optimized'])
|
94
|
-
assert [true, false].include?(response['index']['hasDeletions'])
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class HTTPUtilTest < RSolrBaseTest
|
4
|
-
|
5
|
-
class DummyClass
|
6
|
-
include RSolr::Connection::Utils
|
7
|
-
end
|
8
|
-
|
9
|
-
def setup
|
10
|
-
@c = DummyClass.new
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_build_url
|
14
|
-
assert_equal '/something', @c.build_url('/something')
|
15
|
-
assert_equal '/something?q=Testing', @c.build_url('/something', :q=>'Testing')
|
16
|
-
assert_equal '/something?array=1&array=2&array=3', @c.build_url('/something', :array=>[1, 2, 3])
|
17
|
-
result = @c.build_url('/something', :q=>'A', :array=>[1, 2, 3])
|
18
|
-
assert result=~/^\/something\?/
|
19
|
-
assert result=~/q=A/
|
20
|
-
assert result=~/array=1/
|
21
|
-
assert result=~/array=2/
|
22
|
-
assert result=~/array=3/
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_escape
|
26
|
-
assert_equal '%2B', @c.escape('+')
|
27
|
-
assert_equal 'This+is+a+test', @c.escape('This is a test')
|
28
|
-
assert_equal '%3C%3E%2F%5C', @c.escape('<>/\\')
|
29
|
-
assert_equal '%22', @c.escape('"')
|
30
|
-
assert_equal '%3A', @c.escape(':')
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_hash_to_query
|
34
|
-
my_params = {
|
35
|
-
:z=>'should be whatever',
|
36
|
-
:q=>'test',
|
37
|
-
:d=>[1, 2, 3, 4],
|
38
|
-
:b=>:zxcv,
|
39
|
-
:x=>['!', '*', nil]
|
40
|
-
}
|
41
|
-
result = @c.hash_to_query(my_params)
|
42
|
-
assert result=~/z=should\+be\+whatever/
|
43
|
-
assert result=~/q=test/
|
44
|
-
assert result=~/d=1/
|
45
|
-
assert result=~/d=2/
|
46
|
-
assert result=~/d=3/
|
47
|
-
assert result=~/d=4/
|
48
|
-
assert result=~/b=zxcv/
|
49
|
-
assert result=~/x=%21/
|
50
|
-
assert result=~/x=*/
|
51
|
-
assert result=~/x=&?/
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_ampersand_within_query_value
|
55
|
-
my_params = {
|
56
|
-
"fq" => "building_facet:\"Green (Humanities & Social Sciences)\""
|
57
|
-
}
|
58
|
-
expected = 'fq=building_facet%3A%22Green+%28Humanities+%26+Social+Sciences%29%22'
|
59
|
-
assert_equal expected, @c.hash_to_query(my_params)
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_brackets
|
63
|
-
assert_equal '%7B', @c.escape('{')
|
64
|
-
assert_equal '%7D', @c.escape('}')
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_exclamation
|
68
|
-
assert_equal '%21', @c.escape('!')
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_complex_solr_query1
|
72
|
-
my_params = {'fq' => '{!raw f=field_name}crazy+\"field+value'}
|
73
|
-
expected = 'fq=%7B%21raw+f%3Dfield_name%7Dcrazy%2B%5C%22field%2Bvalue'
|
74
|
-
assert_equal expected, @c.hash_to_query(my_params)
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_complex_solr_query2
|
78
|
-
my_params = {'q' => '+popularity:[10 TO *] +section:0'}
|
79
|
-
expected = 'q=%2Bpopularity%3A%5B10+TO+%2A%5D+%2Bsection%3A0'
|
80
|
-
assert_equal expected, @c.hash_to_query(my_params)
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
data/test/helper.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
|
2
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'rsolr')
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
#
|
6
|
-
class Test::Unit::TestCase
|
7
|
-
|
8
|
-
def self.test(name, &block)
|
9
|
-
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
10
|
-
defined = instance_method(test_name) rescue false
|
11
|
-
raise "#{test_name} is already defined in #{self}" if defined
|
12
|
-
if block_given?
|
13
|
-
define_method(test_name, &block)
|
14
|
-
else
|
15
|
-
define_method(test_name) do
|
16
|
-
flunk "No implementation provided for #{name}"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
class RSolrBaseTest < Test::Unit::TestCase
|
24
|
-
|
25
|
-
def assert_class(expected, instance)
|
26
|
-
assert_equal expected, instance.class
|
27
|
-
end
|
28
|
-
|
29
|
-
def default_test
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
begin
|
36
|
-
require 'rubygems'
|
37
|
-
require 'redgreen'
|
38
|
-
rescue LoadError
|
39
|
-
end
|
40
|
-
|
41
|
-
def mock_query_response
|
42
|
-
%({'responseHeader'=>{
|
43
|
-
'status'=>0,'QTime'=>43,'params'=>{
|
44
|
-
'q'=>'*:*','wt'=>'ruby','echoParams'=>'EXPLICIT'
|
45
|
-
}
|
46
|
-
},
|
47
|
-
'response'=>{
|
48
|
-
'numFound'=>26,'start'=>0,'docs'=>[
|
49
|
-
{'id'=>'SP2514N','inStock'=>true,'manu'=>'Samsung Electronics Co. Ltd.','name'=>'Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133','popularity'=>6,'price'=>92.0,'sku'=>'SP2514N','timestamp'=>'2008-11-21T17:21:55.601Z','cat'=>['electronics','hard drive'],'spell'=>['Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133'],'features'=>['7200RPM, 8MB cache, IDE Ultra ATA-133','NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor']},
|
50
|
-
{'id'=>'6H500F0','inStock'=>true,'manu'=>'Maxtor Corp.','name'=>'Maxtor DiamondMax 11 - hard drive - 500 GB - SATA-300','popularity'=>6,'price'=>350.0,'sku'=>'6H500F0','timestamp'=>'2008-11-21T17:21:55.617Z','cat'=>['electronics','hard drive'],'spell'=>['Maxtor DiamondMax 11 - hard drive - 500 GB - SATA-300'],'features'=>['SATA 3.0Gb/s, NCQ','8.5ms seek','16MB cache']},
|
51
|
-
{'id'=>'F8V7067-APL-KIT','inStock'=>false,'manu'=>'Belkin','name'=>'Belkin Mobile Power Cord for iPod w/ Dock','popularity'=>1,'price'=>19.95,'sku'=>'F8V7067-APL-KIT','timestamp'=>'2008-11-21T17:21:55.652Z','weight'=>4.0,'cat'=>['electronics','connector'],'spell'=>['Belkin Mobile Power Cord for iPod w/ Dock'],'features'=>['car power adapter, white']},
|
52
|
-
{'id'=>'IW-02','inStock'=>false,'manu'=>'Belkin','name'=>'iPod & iPod Mini USB 2.0 Cable','popularity'=>1,'price'=>11.5,'sku'=>'IW-02','timestamp'=>'2008-11-21T17:21:55.657Z','weight'=>2.0,'cat'=>['electronics','connector'],'spell'=>['iPod & iPod Mini USB 2.0 Cable'],'features'=>['car power adapter for iPod, white']},
|
53
|
-
{'id'=>'MA147LL/A','inStock'=>true,'includes'=>'earbud headphones, USB cable','manu'=>'Apple Computer Inc.','name'=>'Apple 60 GB iPod with Video Playback Black','popularity'=>10,'price'=>399.0,'sku'=>'MA147LL/A','timestamp'=>'2008-11-21T17:21:55.681Z','weight'=>5.5,'cat'=>['electronics','music'],'spell'=>['Apple 60 GB iPod with Video Playback Black'],'features'=>['iTunes, Podcasts, Audiobooks','Stores up to 15,000 songs, 25,000 photos, or 150 hours of video','2.5-inch, 320x240 color TFT LCD display with LED backlight','Up to 20 hours of battery life','Plays AAC, MP3, WAV, AIFF, Audible, Apple Lossless, H.264 video','Notes, Calendar, Phone book, Hold button, Date display, Photo wallet, Built-in games, JPEG photo playback, Upgradeable firmware, USB 2.0 compatibility, Playback speed control, Rechargeable capability, Battery level indication']},
|
54
|
-
{'id'=>'TWINX2048-3200PRO','inStock'=>true,'manu'=>'Corsair Microsystems Inc.','name'=>'CORSAIR XMS 2GB (2 x 1GB) 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) Dual Channel Kit System Memory - Retail','popularity'=>5,'price'=>185.0,'sku'=>'TWINX2048-3200PRO','timestamp'=>'2008-11-21T17:21:55.706Z','cat'=>['electronics','memory'],'spell'=>['CORSAIR XMS 2GB (2 x 1GB) 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) Dual Channel Kit System Memory - Retail'],'features'=>['CAS latency 2, 2-3-3-6 timing, 2.75v, unbuffered, heat-spreader']},
|
55
|
-
{'id'=>'VS1GB400C3','inStock'=>true,'manu'=>'Corsair Microsystems Inc.','name'=>'CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail','popularity'=>7,'price'=>74.99,'sku'=>'VS1GB400C3','timestamp'=>'2008-11-21T17:21:55.71Z','cat'=>['electronics','memory'],'spell'=>['CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail']},
|
56
|
-
{'id'=>'VDBDB1A16','inStock'=>true,'manu'=>'A-DATA Technology Inc.','name'=>'A-DATA V-Series 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - OEM','popularity'=>5,'sku'=>'VDBDB1A16','timestamp'=>'2008-11-21T17:21:55.712Z','cat'=>['electronics','memory'],'spell'=>['A-DATA V-Series 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - OEM'],'features'=>['CAS latency 3, 2.7v']},
|
57
|
-
{'id'=>'3007WFP','inStock'=>true,'includes'=>'USB cable','manu'=>'Dell, Inc.','name'=>'Dell Widescreen UltraSharp 3007WFP','popularity'=>6,'price'=>2199.0,'sku'=>'3007WFP','timestamp'=>'2008-11-21T17:21:55.724Z','weight'=>401.6,'cat'=>['electronics','monitor'],'spell'=>['Dell Widescreen UltraSharp 3007WFP'],'features'=>['30" TFT active matrix LCD, 2560 x 1600, .25mm dot pitch, 700:1 contrast']},
|
58
|
-
{'id'=>'VA902B','inStock'=>true,'manu'=>'ViewSonic Corp.','name'=>'ViewSonic VA902B - flat panel display - TFT - 19"','popularity'=>6,'price'=>279.95,'sku'=>'VA902B','timestamp'=>'2008-11-21T17:21:55.734Z','weight'=>190.4,'cat'=>['electronics','monitor'],'spell'=>['ViewSonic VA902B - flat panel display - TFT - 19"'],'features'=>['19" TFT active matrix LCD, 8ms response time, 1280 x 1024 native resolution']}]
|
59
|
-
}
|
60
|
-
})
|
61
|
-
end
|
data/test/message_test.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
class BuilderMessageTest < RSolrBaseTest
|
5
|
-
|
6
|
-
def builder
|
7
|
-
@builder ||= RSolr::Message::Builder.new
|
8
|
-
end
|
9
|
-
|
10
|
-
# call all of the simple methods...
|
11
|
-
# make sure the xml string is valid
|
12
|
-
# ensure the class is actually Solr::XML
|
13
|
-
def test_simple_methods
|
14
|
-
[:optimize, :rollback, :commit].each do |meth|
|
15
|
-
result = self.builder.send(meth)
|
16
|
-
assert_equal "<#{meth}/>", result.to_s
|
17
|
-
assert_equal String, result.class
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_add_yields_doc_objects_if_block_given
|
22
|
-
documents = [{:id=>1, :name=>'sam', :cat=>['cat 1', 'cat 2']}]
|
23
|
-
add_attrs = {:boost=>200.00}
|
24
|
-
result = self.builder.add(documents, add_attrs) do |doc|
|
25
|
-
doc.field_by_name(:name).attrs[:boost] = 10
|
26
|
-
assert_equal 4, doc.fields.size
|
27
|
-
assert_equal 2, doc.fields_by_name(:cat).size
|
28
|
-
end
|
29
|
-
#<add boost="200.0">
|
30
|
-
#<doc>
|
31
|
-
#<field name="cat">cat 1</field>
|
32
|
-
#<field name="cat">cat 2</field>
|
33
|
-
#<field name="name" boost="10">sam</field>
|
34
|
-
#<field name="id">1</field>
|
35
|
-
#</doc>
|
36
|
-
#</add>
|
37
|
-
assert result =~ %r(name="cat">cat 1</field>)
|
38
|
-
assert result =~ %r(name="cat">cat 2</field>)
|
39
|
-
assert result =~ %r(<add boost="200.0">)
|
40
|
-
assert result =~ %r(boost="10")
|
41
|
-
assert result =~ %r(<field name="id">1</field>)
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_delete_by_id
|
45
|
-
result = self.builder.delete_by_id(10)
|
46
|
-
assert_equal String, result.class
|
47
|
-
assert_equal '<delete><id>10</id></delete>', result.to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_delete_by_multiple_ids
|
51
|
-
result = self.builder.delete_by_id([1, 2, 3])
|
52
|
-
assert_equal String, result.class
|
53
|
-
assert_equal '<delete><id>1</id><id>2</id><id>3</id></delete>', result.to_s
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_delete_by_query
|
57
|
-
result = self.builder.delete_by_query('status:"LOST"')
|
58
|
-
assert_equal String, result.class
|
59
|
-
assert_equal '<delete><query>status:"LOST"</query></delete>', result.to_s
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_delete_by_multiple_queries
|
63
|
-
result = self.builder.delete_by_query(['status:"LOST"', 'quantity:0'])
|
64
|
-
assert_equal String, result.class
|
65
|
-
assert_equal '<delete><query>status:"LOST"</query><query>quantity:0</query></delete>', result.to_s
|
66
|
-
end
|
67
|
-
|
68
|
-
# add a single hash ("doc")
|
69
|
-
def test_add_hash
|
70
|
-
data = {
|
71
|
-
:id=>1,
|
72
|
-
:name=>'matt'
|
73
|
-
}
|
74
|
-
assert self.builder.add(data).to_s =~ /<field name="name">matt<\/field>/
|
75
|
-
assert self.builder.add(data).to_s =~ /<field name="id">1<\/field>/
|
76
|
-
end
|
77
|
-
|
78
|
-
# add an array of hashes
|
79
|
-
def test_add_array
|
80
|
-
data = [
|
81
|
-
{
|
82
|
-
:id=>1,
|
83
|
-
:name=>'matt'
|
84
|
-
},
|
85
|
-
{
|
86
|
-
:id=>2,
|
87
|
-
:name=>'sam'
|
88
|
-
}
|
89
|
-
]
|
90
|
-
|
91
|
-
message = self.builder.add(data)
|
92
|
-
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>'
|
93
|
-
|
94
|
-
assert message.to_s=~/<field name="name">matt<\/field>/
|
95
|
-
assert message.to_s=~/<field name="name">sam<\/field>/
|
96
|
-
end
|
97
|
-
|
98
|
-
# multiValue field support test, thanks to Fouad Mardini!
|
99
|
-
def test_add_multi_valued_field
|
100
|
-
data = {
|
101
|
-
:id => 1,
|
102
|
-
:name => ['matt1', 'matt2']
|
103
|
-
}
|
104
|
-
|
105
|
-
result = self.builder.add(data)
|
106
|
-
|
107
|
-
assert result.to_s =~ /<field name="name">matt1<\/field>/
|
108
|
-
assert result.to_s =~ /<field name="name">matt2<\/field>/
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_add_single_document
|
112
|
-
document = RSolr::Message::Document.new
|
113
|
-
document.add_field('id', 1)
|
114
|
-
document.add_field('name', 'matt', :boost => 2.0)
|
115
|
-
result = self.builder.add(document)
|
116
|
-
|
117
|
-
assert result.to_s =~ /<field name="id">1<\/field>/
|
118
|
-
|
119
|
-
# depending on which ruby version, the attributes can be out of place
|
120
|
-
# so we need to test both... there's gotta be a better way to do this?
|
121
|
-
assert(
|
122
|
-
result.to_s =~ /<field name="name" boost="2.0">matt<\/field>/ ||
|
123
|
-
result.to_s =~ /<field boost="2.0" name="name">matt<\/field>/
|
124
|
-
)
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_add_multiple_documents
|
128
|
-
documents = (1..2).map do |i|
|
129
|
-
doc = RSolr::Message::Document.new
|
130
|
-
doc.add_field('id', i)
|
131
|
-
doc.add_field('name', "matt#{i}")
|
132
|
-
doc
|
133
|
-
end
|
134
|
-
result = self.builder.add(documents)
|
135
|
-
|
136
|
-
assert result.to_s =~ /<field name="name">matt1<\/field>/
|
137
|
-
assert result.to_s =~ /<field name="name">matt2<\/field>/
|
138
|
-
end
|
139
|
-
|
140
|
-
end
|
data/test/rsolr_test.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class SolrTest < RSolrBaseTest
|
4
|
-
|
5
|
-
def setup
|
6
|
-
if defined?(JRUBY_VERSION)
|
7
|
-
@solr = RSolr.connect(:adapter=>:direct)
|
8
|
-
else
|
9
|
-
@solr = RSolr.connect
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_escape
|
14
|
-
expected = %q(http\:\/\/lucene\.apache\.org\/solr)
|
15
|
-
source = "http://lucene.apache.org/solr"
|
16
|
-
assert_equal expected, RSolr.escape(source)
|
17
|
-
assert @solr.respond_to?(:escape)
|
18
|
-
assert_equal expected, @solr.escape(source)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|