Class: Supernova::SolrCriteria
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
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
#to_a ⇒ Object
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_params ⇒ Object
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
|