Created
October 29, 2008 17:33
-
-
Save matthewrudy/20759 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SolrQuery.build(:keyword => "red OR yellow", :category => "toys", :price => 5..10) | |
returns | |
"(red OR yellow) AND category:(toys) AND price:([5 TO 10])" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SolrQuery | |
class << self | |
def solr_query(conditions = {}) | |
conditions = conditions.dup # let's not accidentally kill our original params | |
query_parts = [] | |
keyword = conditions.delete(:keyword) # keyword is magical | |
if keyword.present? | |
query_parts << "#{solr_value(keyword, true)}" | |
end | |
conditions.each do |field, value| | |
unless value.nil? | |
query_parts << "#{field}:(#{solr_value(value)})" | |
end | |
end | |
if query_parts.empty? | |
return "" | |
else | |
return query_parts.join(" AND ") | |
end | |
end | |
alias :build :solr_query | |
def solr_value(object, downcase=false) | |
if object.is_a?(Array) # case when Array will break for has_manys | |
if object.empty? | |
string = "NIL" # an empty array should be equivalent to "don't match anything" | |
else | |
string = object.map do |element| | |
solr_value(element, downcase) | |
end.join(" OR ") | |
downcase = false # don't downcase the ORs | |
end | |
elsif object.is_a?(Hash) || object.is_a?(Range) | |
return solr_range(object) # avoid escaping the * | |
elsif object.is_a?(ActiveRecord::Base) | |
string = object.id.to_s | |
elsif object.is_a?(String) | |
if downcase && (bits = object.split(" OR ")) && bits.length > 1 | |
return "(#{solr_value(bits, downcase)})" | |
else | |
string = object | |
end | |
else | |
string = object.to_s | |
end | |
string.downcase! if downcase | |
return escape_solr_string(string) | |
end | |
protected :solr_value | |
def solr_range(object) | |
min = max = nil | |
if object.is_a?(Hash) | |
min = object[:min] | |
max = object[:max] | |
else | |
min = object.first | |
max = object.last | |
end | |
min = solr_value(min) if min | |
max = solr_value(max) if max | |
min ||= "*" | |
max ||= "*" | |
return "[#{min} TO #{max}]" | |
end | |
protected :solr_range | |
def escape_solr_string(string) | |
string.gsub(SOLR_ESCAPE_REGEXP, "\\\\\\0").strip | |
end | |
protected :escape_solr_string | |
end | |
SOLR_ESCAPE_CHARACTERS = %w" \ + - ! ( ) : ^ ] { } ~ * ? " | |
SOLR_ESCAPE_REGEXP = Regexp.new(SOLR_ESCAPE_CHARACTERS.map{|char| Regexp.escape(char)}.join("|")) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment