Class: Sunspot::Search

Inherits:
Object
  • Object
show all
Defined in:
lib/sunspot/search.rb,
lib/sunspot/search/hit.rb,
lib/sunspot/search/facet_row.rb,
lib/sunspot/search/highlight.rb,
lib/sunspot/search/date_facet.rb,
lib/sunspot/search/field_facet.rb,
lib/sunspot/search/query_facet.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.

Defined Under Namespace

Classes: DateFacet, FacetRow, FieldFacet, Highlight, Hit, QueryFacet

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, setup, query, configuration) ⇒ Search

:nodoc:



20
21
22
23
24
# File 'lib/sunspot/search.rb', line 20

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

Instance Attribute Details

#queryObject (readonly)

Query information for this search. If you wish to build the query without using the search DSL, this method allows you to access the query API directly. See Sunspot#new_search for how to construct the search object in this case.



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

def query
  @query
end

Instance Method Details

#add_date_facet(field, options) ⇒ Object

:nodoc:



183
184
185
# File 'lib/sunspot/search.rb', line 183

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

#add_field_facet(field, options = {}) ⇒ Object

:nodoc:



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

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

#add_query_facet(name, options) ⇒ Object

:nodoc:



187
188
189
# File 'lib/sunspot/search.rb', line 187

def add_query_facet(name, options) #:nodoc:
  @facets[name] = QueryFacet.new(name, self, options)
end

#build(&block) ⇒ Object

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!


151
152
153
154
# File 'lib/sunspot/search.rb', line 151

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

#data_accessor_for(clazz) ⇒ Object

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.



133
134
135
136
# File 'lib/sunspot/search.rb', line 133

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

#dynamic_facet(base_name, dynamic_name) ⇒ Object

Get the facet object for a given dynamic field. This dynamic field will need to have been requested as a field facet inside the search block.

Parameters

base_name<Symbol>

Base name of the dynamic field definiton (as specified in the setup block)

dynamic_name<Symbol>

Dynamic field name to facet on

Returns

Sunspot::Facet

Facet object for given dynamic field

Example

search = Sunspot.search(Post) do
  dynamic :custom do
    facet :cuisine
  end
end
search.dynamic_facet(:custom, :cuisine)
  #=> Facet for the dynamic field :cuisine in the :custom field definition


120
121
122
# File 'lib/sunspot/search.rb', line 120

def dynamic_facet(base_name, dynamic_name)
  facet(:"#{base_name}:#{dynamic_name}")
end

#executeObject Also known as: 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.



33
34
35
36
37
38
# File 'lib/sunspot/search.rb', line 33

def execute
  reset
  params = @query.to_params
  @solr_result = @connection.select(params)
  self
end

#facet(name) ⇒ Object

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.



90
91
92
# File 'lib/sunspot/search.rb', line 90

def facet(name)
  @facets[name]
end

#facet_responseObject

:nodoc:



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

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

#hitsObject 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.

Returns

Array

Ordered collection of Hit objects



69
70
71
# File 'lib/sunspot/search.rb', line 69

def hits
  @hits ||= solr_response['docs'].map { |doc| Hit.new(doc, highlights_for(doc), self) }
end

#inspectObject

:nodoc:



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

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

#populate_hits!Object

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.



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

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_for(Util.full_const_get(class_name)).load_all(ids).each do |instance|
      hit = id_hit_hash[class_name][Adapters::InstanceAdapter.adapt(instance).id.to_s]
      hit.instance = instance
    end
  end
end

#resultsObject

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.

Returns

WillPaginate::Collection or Array

Instantiated result objects



50
51
52
53
54
55
56
57
58
# File 'lib/sunspot/search.rb', line 50

def results
  @results ||= if @query.page && defined?(WillPaginate::Collection)
    WillPaginate::Collection.create(@query.page, @query.per_page, total) do |pager|
      pager.replace(hits.map { |hit| hit.instance })
    end
  else
    hits.map { |hit| hit.instance }
  end
end

#totalObject

The total number of documents matching the query parameters

Returns

Integer

Total matching documents



81
82
83
# File 'lib/sunspot/search.rb', line 81

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