Class: RSolr::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/rsolr/client.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, options = {}) ⇒ Client

Returns a new instance of Client.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rsolr/client.rb', line 18

def initialize connection, options = {}
  @proxy = @uri = nil
  @connection = connection
  unless false === options[:url]
    url = options[:url] ? options[:url].dup : 'http://127.0.0.1:8983/solr/'
    url << "/" unless url[-1] == ?/
    @uri = ::URI.parse(url)
    if options[:proxy]
      proxy_url = options[:proxy].dup
      proxy_url << "/" unless proxy_url.nil? or proxy_url[-1] == ?/
      @proxy = ::URI.parse proxy_url if proxy_url
    elsif options[:proxy] == false
      @proxy = false  # used to avoid setting the proxy from the environment.
    end
  end
  @update_format = options.delete(:update_format) || RSolr::JSON::Generator
  @update_path = options.fetch(:update_path, 'update')
  @options = options
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (protected)

converts the method name for the solr request handler path.



298
299
300
301
302
303
304
# File 'lib/rsolr/client.rb', line 298

def method_missing name, *args
  if name.to_s =~ /^paginated?_(.+)$/
    paginate args[0], args[1], $1, *args[2..-1]
  else
    send_and_receive name, *args
  end
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



16
17
18
# File 'lib/rsolr/client.rb', line 16

def options
  @options
end

#proxyObject (readonly)

Returns the value of attribute proxy.



16
17
18
# File 'lib/rsolr/client.rb', line 16

def proxy
  @proxy
end

#update_formatObject (readonly)

Returns the value of attribute update_format.



16
17
18
# File 'lib/rsolr/client.rb', line 16

def update_format
  @update_format
end

#update_pathObject (readonly)

Returns the value of attribute update_path.



16
17
18
# File 'lib/rsolr/client.rb', line 16

def update_path
  @update_path
end

#uriObject (readonly)

Returns the value of attribute uri.



16
17
18
# File 'lib/rsolr/client.rb', line 16

def uri
  @uri
end

Class Method Details

.default_wtObject



7
8
9
# File 'lib/rsolr/client.rb', line 7

def default_wt
  @default_wt ||= :json
end

.default_wt=(value) ⇒ Object



11
12
13
# File 'lib/rsolr/client.rb', line 11

def default_wt= value
  @default_wt = value
end

Instance Method Details

#adapt_response(request, response) ⇒ Object

This method will evaluate the :body value if the params.params == :ruby … otherwise, the body is returned as is. The return object has methods attached, :request and :response. These methods give you access to the original request and response from the connection.

adapt_response will raise an InvalidRubyResponse if :wt == :ruby and the body couldn’t be evaluated.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/rsolr/client.rb', line 259

def adapt_response request, response
  raise "The response does not have the correct keys => :body, :headers, :status" unless
    %W(body headers status) == response.keys.map{|k|k.to_s}.sort

  result = if respond_to? "evaluate_#{request[:params][:wt]}_response", true
    send "evaluate_#{request[:params][:wt]}_response", request, response
  else
    response[:body]
  end

  if result.is_a?(Hash) || request[:method] == :head
    result = RSolr::HashWithResponse.new(request, response, result)
  end

  result
end

#add(doc, opts = {}) ⇒ Object

add creates xml “add” documents and sends the xml data to the update method

wiki.apache.org/solr/UpdateXmlMessages#add.2BAC8-update

single record: solr.add(:id=>1, :name=>‘one’)

add using an array

solr.add(

[{:id=>1, :name=>'one'}, {:id=>2, :name=>'two'}],
:add_attributes => {:boost=>5.0, :commitWithin=>10}

)



100
101
102
103
# File 'lib/rsolr/client.rb', line 100

def add doc, opts = {}
  add_attributes = opts.delete :add_attributes
  update opts.merge(:data => builder.add(doc, add_attributes))
end

#base_request_uriObject

returns the request uri object.



39
40
41
# File 'lib/rsolr/client.rb', line 39

def base_request_uri
  base_uri.request_uri if base_uri
end

#base_uriObject

returns the URI uri object.



44
45
46
# File 'lib/rsolr/client.rb', line 44

def base_uri
  @uri
end

#build_paginated_request(page, per_page, path, opts) ⇒ Object



240
241
242
243
244
245
246
247
# File 'lib/rsolr/client.rb', line 240

def build_paginated_request page, per_page, path, opts
  per_page = per_page.to_s.to_i
  page = page.to_s.to_i-1
  page = page < 1 ? 0 : page
  opts[:params]["start"] = page * per_page
  opts[:params]["rows"] = per_page
  build_request path, opts
end

#build_request(path, opts) ⇒ Object

build_request accepts a path and options hash, then prepares a normalized hash to return for sending to a solr connection driver. build_request sets up the uri/query string and converts the data arg to form-urlencoded, if the data arg is a hash. returns a hash with the following keys:

:method
:params
:headers
:data
:uri
:path
:query


214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/rsolr/client.rb', line 214

def build_request path, opts
  raise "path must be a string or symbol, not #{path.inspect}" unless [String,Symbol].include?(path.class)
  path = path.to_s
  opts[:proxy] = proxy unless proxy.nil?
  opts[:method] ||= :get
  raise "The :data option can only be used if :method => :post" if opts[:method] != :post and opts[:data]
  opts[:params] = params_with_wt(opts[:params])
  query = RSolr::Uri.params_to_solr(opts[:params]) unless opts[:params].empty?
  opts[:query] = query
  if opts[:data].is_a? Hash
    opts[:data] = RSolr::Uri.params_to_solr opts[:data]
    opts[:headers] ||= {}
    opts[:headers]['Content-Type'] ||= 'application/x-www-form-urlencoded; charset=UTF-8'
  end
  opts[:path] = path
  opts[:uri] = base_uri.merge(path.to_s + (query ? "?#{query}" : "")) if base_uri

  opts
end

#builderObject



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/rsolr/client.rb', line 149

def builder
  @builder ||= if update_format.is_a? Class
                 update_format.new
               elsif update_format == :json
                 RSolr::JSON::Generator.new
               elsif update_format == :xml
                 RSolr::Xml::Generator.new
               else
                 update_format
               end
end

#commit(opts = {}) ⇒ Object



109
110
111
112
# File 'lib/rsolr/client.rb', line 109

def commit opts = {}
  commit_attrs = opts.delete :commit_attributes
  update opts.merge(:data => builder.commit( commit_attrs ))
end

#connectionObject



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/rsolr/client.rb', line 276

def connection
  @connection ||= begin
    conn_opts = { request: {} }
    conn_opts[:proxy] = proxy if proxy
    conn_opts[:request][:open_timeout] = options[:open_timeout] if options[:open_timeout]
    conn_opts[:request][:timeout] = options[:read_timeout] if options[:read_timeout]
    conn_opts[:request][:params_encoder] = Faraday::FlatParamsEncoder

    Faraday.new(conn_opts) do |conn|
      conn.basic_auth(uri.user, uri.password) if uri.user && uri.password
      conn.response :raise_error
      conn.request :retry, max: options[:retry_after_limit], interval: 0.05,
                           interval_randomness: 0.5, backoff_factor: 2,
                           exceptions: ['Faraday::Error', 'Timeout::Error'] if options[:retry_503]
      conn.adapter options[:adapter] || Faraday.default_adapter
    end
  end
end

#delete_by_id(id, opts = {}) ⇒ Object

Delete one or many documents by id

solr.delete_by_id 10
solr.delete_by_id([12, 41, 199])


135
136
137
# File 'lib/rsolr/client.rb', line 135

def delete_by_id id, opts = {}
  update opts.merge(:data => builder.delete_by_id(id))
end

#delete_by_query(query, opts = {}) ⇒ Object

delete one or many documents by query.

wiki.apache.org/solr/UpdateXmlMessages#A.22delete.22_by_ID_and_by_Query

solr.delete_by_query 'available:0'
solr.delete_by_query ['quantity:0', 'manu:"FQ"']


145
146
147
# File 'lib/rsolr/client.rb', line 145

def delete_by_query query, opts = {}
  update opts.merge(:data => builder.delete_by_query(query))
end

#execute(request_context) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/rsolr/client.rb', line 184

def execute request_context
  raw_response = begin
    response = connection.send(request_context[:method], request_context[:uri].to_s) do |req|
      req.body = request_context[:data] if request_context[:method] == :post and request_context[:data]
      req.headers.merge!(request_context[:headers]) if request_context[:headers]
    end

    { status: response.status.to_i, headers: response.headers, body: response.body.force_encoding('utf-8') }
  rescue Faraday::ClientError => e
    raise RSolr::Error::Http.new(request_context, e.response)
  rescue Errno::ECONNREFUSED
    raise RSolr::Error::ConnectionRefused, request_context.inspect
  end
  adapt_response(request_context, raw_response) unless raw_response.nil?
end

#optimize(opts = {}) ⇒ Object



118
119
120
121
# File 'lib/rsolr/client.rb', line 118

def optimize opts = {}
  optimize_attributes = opts.delete :optimize_attributes
  update opts.merge(:data => builder.optimize(optimize_attributes))
end

#paginate(page, per_page, path, opts = nil) ⇒ Object

A paginated request method. Converts the page and per_page arguments into “rows” and “start”.



60
61
62
63
64
65
# File 'lib/rsolr/client.rb', line 60

def paginate page, per_page, path, opts = nil
  opts ||= {}
  opts[:params] ||= {}
  raise "'rows' or 'start' params should not be set when using +paginate+" if ["start", "rows"].include?(opts[:params].keys)
  execute build_paginated_request(page, per_page, path, opts)
end

#params_with_wt(params) ⇒ Object



234
235
236
237
238
# File 'lib/rsolr/client.rb', line 234

def params_with_wt(params)
  return { wt: default_wt } if params.nil?
  return params if params.key?(:wt) || params.key?('wt')
  { wt: default_wt }.merge(params)
end

#rollback(opts = {}) ⇒ Object

send </rollback>

wiki.apache.org/solr/UpdateXmlMessages#A.22rollback.22

NOTE: solr 1.4 only



128
129
130
# File 'lib/rsolr/client.rb', line 128

def rollback opts = {}
  update opts.merge(:data => builder.rollback)
end

#send_and_receive(path, opts) ⇒ Object

send_and_receive is the main request method responsible for sending requests to the connection object.

“path” : A string value that usually represents a solr request handler “opts” : A hash, which can contain the following keys:

:method : required - the http method (:get, :post or :head)
:params : optional - the query string params in hash form
:data : optional - post data -- if a hash is given, it's sent as "application/x-www-form-urlencoded; charset=UTF-8"
:headers : optional - hash of request headers

All other options are passed right along to the connection’s send_and_receive method (:get, :post, or :head)

send_and_receive returns either a string or hash on a successful ruby request. When the :params => :ruby, the response will be a hash, else a string.

creates a request context hash, sends it to the connection’s execute method which returns a simple hash, then passes the request/response into adapt_response.



178
179
180
181
# File 'lib/rsolr/client.rb', line 178

def send_and_receive path, opts
  request_context = build_request path, opts
  execute request_context
end

#update(opts = {}) ⇒ Object

POST XML messages to /update with optional params.

wiki.apache.org/solr/UpdateXmlMessages#add.2BAC8-update

If not set, opts will be set to a hash with the key ‘Content-Type’ set to ‘text/xml’

opts can/should contain:

:data - posted data
:headers - http headers
:params - solr query parameter hash


80
81
82
83
84
# File 'lib/rsolr/client.rb', line 80

def update opts = {}
  opts[:headers] ||= {}
  opts[:headers]['Content-Type'] ||= builder.content_type
  post opts.fetch(:path, update_path), opts
end