Class: Sunspot::Search::AbstractSearch

Inherits:
Object
  • Object
show all
Defined in:
sunspot/lib/sunspot/search/abstract_search.rb

Overview

This class encapsulates the results of a Solr search. It provides access to search results, total result count, facets, and pagination information. Instances of Search are returned by the Sunspot.search and Sunspot.new_search methods.

Direct Known Subclasses

MoreLikeThisSearch, StandardSearch

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (AbstractSearch) initialize(connection, setup, query, configuration)

:nodoc:



21
22
23
24
25
26
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 21

def initialize(connection, setup, query, configuration) #:nodoc:
  @connection, @setup, @query = connection, setup, query
  @query.paginate(1, configuration.pagination.default_per_page)
  @facets = []
  @facets_by_name = {}
end

Instance Attribute Details

- (Object) facets (readonly)

Retrieve all facet objects defined for this search, in order they were defined. To retrieve an individual facet by name, use #facet()



17
18
19
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 17

def facets
  @facets
end

- (Object) query (readonly)

:nodoc:



18
19
20
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 18

def query
  @query
end

- (Object) request_handler

Returns the value of attribute request_handler



19
20
21
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 19

def request_handler
  @request_handler
end

Instance Method Details

- (Object) add_date_facet(field, options)

:nodoc:



249
250
251
252
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 249

def add_date_facet(field, options) #:nodoc:
  name = (options[:name] || field.name)
  add_facet(name, DateFacet.new(field, self, options))
end

- (Object) add_field_facet(field, options = {})

:nodoc:



240
241
242
243
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 240

def add_field_facet(field, options = {}) #:nodoc:
  name = (options[:name] || field.name)
  add_facet(name, FieldFacet.new(field, self, options))
end

- (Object) add_query_facet(name, options)

:nodoc:



245
246
247
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 245

def add_query_facet(name, options) #:nodoc:
  add_facet(name, QueryFacet.new(name, self, options))
end

- (Object) build(&block)

Build this search using a DSL block. This method can be called more than once on an unexecuted search (e.g., Sunspot.new_search) in order to build a search incrementally.

Example

  search = Sunspot.new_search(Post)
  search.build do
    with(:published_at).less_than Time.now
  end
  search.execute


209
210
211
212
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 209

def build(&block)
  Util.instance_eval_or_call(dsl, &block)
  self
end

- (Object) data_accessor_for(clazz)

Get the data accessor that will be used to load a particular class out of persistent storage. Data accessors can implement any methods that may be useful for refining how data is loaded out of storage. When building a search manually (e.g., using the Sunspot#new_search method), this should be used before calling #execute(). Use the Sunspot::DSL::Search#data_accessor_for method when building searches using the block DSL.



191
192
193
194
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 191

def data_accessor_for(clazz) #:nodoc:
  (@data_accessors ||= {})[clazz.name.to_sym] ||=
    Adapters::DataAccessor.create(clazz)
end

- (Object) dynamic_facet(base_name, dynamic_name)

Deprecated in favor of optional second argument to #facet



174
175
176
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 174

def dynamic_facet(base_name, dynamic_name) #:nodoc:
  facet(base_name, dynamic_name)
end

- (Object) each_hit_with_result

Convenience method to iterate over hit and result objects. Block is yielded a Sunspot::Server::Hit instance and a Sunspot::Server::Result instance.

Note that this method iterates over verified hits (see #hits method for more information).



104
105
106
107
108
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 104

def each_hit_with_result
  verified_hits.each do |hit|
    yield(hit, hit.result)
  end
end

- (Object) execute

Execute the search on the Solr instance and store the results. If you use Sunspot#search() to construct your searches, there is no need to call this method as it has already been called. If you use Sunspot#new_search(), you will need to call this method after building the query.



35
36
37
38
39
40
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 35

def execute
  reset
  params = @query.to_params
  @solr_result = @connection.post "#{request_handler}", :data => params
  self
end

- (Object) execute!

:nodoc: deprecated



42
43
44
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 42

def execute! #:nodoc: deprecated
  execute
end

- (Object) facet(name, dynamic_name = nil)

Get the facet object for the given name. `name` can either be the name given to a query facet, or the field name of a field facet. Returns a Sunspot::Facet object.

Parameters

name

Name of the field to return the facet for, or the name given to the query facet when the search was constructed.

dynamic_name

If faceting on a dynamic field, this is the dynamic portion of the field name.

Example:

  search = Sunspot.search(Post) do
    facet :category_ids
    dynamic :custom do
      facet :cuisine
    end
    facet :age do
      row 'Less than a month' do
        with(:published_at).greater_than(1.month.ago)
      end
      row 'Less than a year' do
        with(:published_at, 1.year.ago..1.month.ago)
      end
      row 'More than a year' do
        with(:published_at).less_than(1.year.ago)
      end
    end
  end
  search.facet(:category_ids)
    #=> Facet for :category_ids field
  search.facet(:custom, :cuisine)
    #=> Facet for the dynamic field :cuisine in the :custom field definition
  search.facet(:age)
    #=> Facet for the query facet named :age


161
162
163
164
165
166
167
168
169
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 161

def facet(name, dynamic_name = nil)
  if name
    if dynamic_name
      @facets_by_name[:#{name}:#{dynamic_name}"]
    else
      @facets_by_name[name.to_sym]
    end
  end
end

- (Object) facet_response

:nodoc:



178
179
180
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 178

def facet_response #:nodoc:
  @solr_result['facet_counts']
end

- (Object) hits(options = {}) Also known as: raw_results

Access raw Solr result information. Returns a collection of Hit objects that contain the class name, primary key, keyword relevance score (if applicable), and any stored fields.

Options (options)

:verify

Only return hits that reference objects that actually exist in the data store. This causes results to be eager-loaded from the data store, unlike the normal behavior of this method, which only loads the referenced results when Hit#result is first called.

Returns

Array

Ordered collection of Hit objects



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 79

def hits(options = {})
  if options[:verify]
    verified_hits
  else
    @hits ||=
      begin
        hits = if solr_response && solr_response['docs']
          solr_response['docs'].map do |doc|
            Hit.new(doc, highlights_for(doc), self)
          end
        end
        paginate_collection(hits || [])
      end
  end
end

- (Object) inspect

:nodoc:



236
237
238
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 236

def inspect #:nodoc:
  "<Sunspot::Search:#{query.to_params.inspect}>"
end

- (Object) populate_hits

Populate the Hit objects with their instances. This is invoked the first time any hit has its instance requested, and all hits are loaded as a batch.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 219

def populate_hits #:nodoc:
  id_hit_hash = Hash.new { |h, k| h[k] = {} }
  hits.each do |hit|
    id_hit_hash[hit.class_name][hit.primary_key] = hit
  end
  id_hit_hash.each_pair do |class_name, hits|
    ids = hits.map { |id, hit| hit.primary_key }
    data_accessor = data_accessor_for(Util.full_const_get(class_name))
    hits_for_class = id_hit_hash[class_name]
    data_accessor.load_all(ids).each do |result|
      hit = hits_for_class.delete(Adapters::InstanceAdapter.adapt(result).id.to_s)
      hit.result = result
    end
    hits_for_class.values.each { |hit| hit.result = nil }
  end
end

- (Object) results

Get the collection of results as instantiated objects. If WillPaginate is available, the results will be a WillPaginate::Collection instance; if not, it will be a vanilla Array.

If not all of the results referenced by the Solr hits actually exist in the data store, Sunspot will only return the results that do exist.

Returns

WillPaginate::Collection or Array

Instantiated result objects



58
59
60
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 58

def results
  @results ||= paginate_collection(verified_hits.map { |hit| hit.instance })
end

- (Object) total

The total number of documents matching the query parameters

Returns

Integer

Total matching documents



117
118
119
# File 'sunspot/lib/sunspot/search/abstract_search.rb', line 117

def total
  @total ||= solr_response['numFound'] || 0
end