Class: Supernova::SolrCriteria

Inherits:
Criteria
  • Object
show all
Defined in:
lib/supernova/solr_criteria.rb

Constant Summary

Constants inherited from Criteria

Criteria::DEFAULT_PER_PAGE, Criteria::FIRST_PAGE

Instance Attribute Summary

Attributes inherited from Criteria

#clazz, #filters, #search_options

Instance Method Summary collapse

Methods inherited from Criteria

#attribute_mapping, #conditions, #current_page, #for_classes, #group_by, #implement_in_subclass, #initialize, #limit, #merge, #merge_filters, #merge_filters_array, #merge_filters_or_search_options, #merge_search_options, #method_missing, method_missing, #named_scope_class, #named_scope_defined?, #near, #normalize_coordinates, #options, #order, #paginate, #pagination_attribute_when_greater_zero, #per_page, #read_first_attribute, #search, #select, select, #to_parameters, #where, #with, #within, #without

Constructor Details

This class inherits a constructor from Supernova::Criteria

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Supernova::Criteria

Instance Method Details

#build_doc(hash) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/supernova/solr_criteria.rb', line 89

def build_doc(hash)
  return hash if !hash["type"].respond_to?(:constantize)
  doc = hash["type"].constantize.new
  doc.instance_variable_set("@solr_doc", hash)
  hash.each do |key, value|
    if key == "id"
      doc.id = value.to_s.split("/").last if doc.respond_to?(:id=)
    else
      set_first_responding_attribute(doc, key, value)
    end
  end
  doc.instance_variable_set("@readonly", true)
  doc.instance_variable_set("@new_record", false)
  doc
end

#build_doc_method(method) ⇒ Object



85
86
87
# File 'lib/supernova/solr_criteria.rb', line 85

def build_doc_method(method)
  merge_search_options :build_doc_method, method
end

#build_docs(docs) ⇒ Object



79
80
81
82
83
# File 'lib/supernova/solr_criteria.rb', line 79

def build_docs(docs)
  docs.map do |hash|
    self.search_options[:build_doc_method] ? self.search_options[:build_doc_method].call(hash) : build_doc(hash)
  end
end

#convert_search_order(order) ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/supernova/solr_criteria.rb', line 37

def convert_search_order(order)
  asc_or_desc = nil
  field = solr_field_from_field(order)
  if order.match(/^(.*?) (asc|desc)/i)
    field = solr_field_from_field($1)
    asc_or_desc = $2
  end
  [field, asc_or_desc].compact.join(" ")
end

#fq_filter_for_key_and_value(key, value) ⇒ Object



75
76
77
# File 'lib/supernova/solr_criteria.rb', line 75

def fq_filter_for_key_and_value(key, value)
  "#{key}:#{value.is_a?(Range) ? "[#{value.first} TO #{value.last}]" : value}"
end

#fq_from_with(with) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/supernova/solr_criteria.rb', line 60

def fq_from_with(with)
  if with.blank?
    []
  else
    with.map do |key_or_condition, value|
      if key_or_condition.respond_to?(:solr_filter_for)
        key_or_condition.key = solr_field_from_field(key_or_condition.key)
        key_or_condition.solr_filter_for(value)
      else
        fq_filter_for_key_and_value(solr_field_from_field(key_or_condition), value)
      end
    end
  end
end

#reverse_lookup_solr_field(solr_field) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/supernova/solr_criteria.rb', line 51

def reverse_lookup_solr_field(solr_field)
  if search_options[:attribute_mapping]
    search_options[:attribute_mapping].each do |field, options|
      return field if solr_field.to_s == solr_field_from_field(field)
    end
  end
  solr_field
end

#set_first_responding_attribute(doc, solr_key, value) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/supernova/solr_criteria.rb', line 105

def set_first_responding_attribute(doc, solr_key, value)
  [reverse_lookup_solr_field(solr_key), solr_key].each do |key|
    meth = :"#{key}="
    if doc.respond_to?(meth)
      doc.send(meth, value)
      return
    end
  end
end

#solr_field_from_field(field) ⇒ Object



47
48
49
# File 'lib/supernova/solr_criteria.rb', line 47

def solr_field_from_field(field)
  Supernova::SolrIndexer.solr_field_for_field_name_and_mapping(field, search_options[:attribute_mapping])
end

#to_aObject



115
116
117
118
119
120
# File 'lib/supernova/solr_criteria.rb', line 115

def to_a
  response = Supernova::Solr.connection.get("select", :params => to_params)
  collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
  collection.replace(build_docs(response["response"]["docs"]))
  collection
end

#to_paramsObject

move this into separate methods (test each separatly)



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/supernova/solr_criteria.rb', line 5

def to_params
  solr_options = { :fq => [], :q => "*:*" }
  solr_options[:fq] += fq_from_with(self.filters[:with])
  if self.filters[:without]
   self.filters[:without].each do |field, values| 
     solr_options[:fq] += values.map { |value| "!#{solr_field_from_field(field)}:#{value}" }
   end
  end
  solr_options[:sort] = convert_search_order(self.search_options[:order]) if self.search_options[:order]
  if self.search_options[:search].is_a?(Array)
    solr_options[:q] = self.search_options[:search].map { |query| "(#{query})" }.join(" AND ")
  end
  
  if self.search_options[:geo_center] && self.search_options[:geo_distance]
    solr_options[:pt] = "#{self.search_options[:geo_center][:lat]},#{self.search_options[:geo_center][:lng]}"
    solr_options[:d] = self.search_options[:geo_distance].to_f / Supernova::KM_TO_METER
    solr_options[:sfield] = solr_field_from_field(:location)
    solr_options[:fq] << "{!geofilt}"
  end
  if self.search_options[:select]
    self.search_options[:select] << :id
    solr_options[:fl] = self.search_options[:select].compact.map { |field| solr_field_from_field(field) }.join(",") 
  end
  solr_options[:fq] << "type:#{self.clazz}" if self.clazz
  
  if self.search_options[:pagination]
    solr_options[:rows] = per_page
    solr_options[:start] = (current_page - 1) * solr_options[:rows]
  end
  solr_options
end