Skip to content

Instantly share code, notes, and snippets.

@matthewrudy
Created October 29, 2008 17:33
Show Gist options
  • Save matthewrudy/20759 to your computer and use it in GitHub Desktop.
Save matthewrudy/20759 to your computer and use it in GitHub Desktop.
SolrQuery.build(:keyword => "red OR yellow", :category => "toys", :price => 5..10)
returns
"(red OR yellow) AND category:(toys) AND price:([5 TO 10])"
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