class SolrLite::FilterQuery

Represents an “fq” in Solr. Field is the field to filter by and value the value to filter by. In a Solr query are represented as “fq=field:value”

Attributes

field[RW]
form_value[RW]
qs_value[RW]
remove_url[RW]
solr_value[RW]
title[RW]
value[RW]

Public Class Methods

from_query_string(qs) click to toggle source

qs is assumed to be the value taken from the query string in the form `field|value` or `field|value1|valueN`.

For range values the format is: `field^start,end`

Sometimes(*) the string comes URL encoded, for example:

`field|hello`
`field|hello%20world`

CGI.unespace handles these cases nicer than URL.decode

(*) Values coming from HTML forms submitted via HTTP POST tend to be encoded slighly different than value submitted via HTTP GET requests.

TODO: Should I remove support for multi-values

(e.g. `field|value1|valueN`) since we are
not using them? It will make the code here
and in init_from_values() cleaner.
# File lib/filter_query.rb, line 49
def self.from_query_string(qs)
  is_range = false
  tokens = CGI.unescape(qs).split("|")
  if tokens.count < 2
    tokens = CGI.unescape(qs).split("^")
    return nil if tokens.count != 2
    is_range = true
  end
  field = ""
  values = []
  tokens.each_with_index do |token, i|
    if i == 0
      field = token
    else
      values << token
    end
  end
  FilterQuery.new(field, values, is_range)
end
new(field, values, is_range = false) click to toggle source
# File lib/filter_query.rb, line 11
def initialize(field, values, is_range = false)
  if is_range
    init_from_range(field, values.first)
  else
    init_from_values(field, values)
  end
end

Public Instance Methods

range_from() click to toggle source
# File lib/filter_query.rb, line 19
def range_from()
  tokens = (value || "").split(" - ")
  return nil if tokens.count != 2
  tokens[0].gsub("*","")
end
range_to() click to toggle source
# File lib/filter_query.rb, line 25
def range_to()
  tokens = (value || "").split(" - ")
  return nil if tokens.count != 2
  tokens[1].gsub("*","")
end

Private Instance Methods

init_from_range(field, range_string) click to toggle source

range_string is expected in the form “start,end”

# File lib/filter_query.rb, line 102
def init_from_range(field, range_string)
  @field = field
  tokens = (range_string || "").split(",")
  return nil if tokens.count != 2
  range_start = tokens[0]
  range_end = tokens[1]
  @value = "#{range_start} - #{range_end}"
  @solr_value = to_solr_fq_value_range(field, range_start, range_end)
  @qs_value = "#{field}^#{range_string}"
  @form_value = "#{field}^#{range_string}"  # HTML Form friendly (no encoding, the form auto-encodes on POST)
  @title = field                            # default to field name
  @remove_url = nil
end
init_from_values(field, values) click to toggle source
# File lib/filter_query.rb, line 116
def init_from_values(field, values)
  @field = field
  @value = values.join("|")
  @solr_value = to_solr_fq_value(field, values)
  @qs_value = "#{field}"
  values.each do |v|
    @qs_value += "|#{CGI.escape(v)}"        # URL friendly (no : or quotes)
  end
  @form_value = "#{field}|#{@value}"        # HTML Form friendly (no encoding, the form auto-encodes on POST)
  @title = field                            # default to field name
  @remove_url = nil
end
to_solr_fq_value(field, values) click to toggle source

Creates a filter query (fq) string as needed by Solr from an array of values. Handles single and multi-value gracefully. For single-value it returns “(field:value)”. For multi-value it returns “(field:value1) OR (field:value2)”. We use the multi-value in the Advanced Search when we allow the user to select multiple values for a single facet.

# File lib/filter_query.rb, line 76
def to_solr_fq_value(field, values)
  solr_value = ""
  values.each_with_index do |v, i|
    solr_value += '(' + field + ':"' + v + '")'
    lastValue = (i == (values.length-1))
    if !lastValue
      solr_value += " OR "
    end
  end
  # Very important to escape the : otherwise URL.parse throws an error in Linux
  CGI.escape(solr_value)
end
to_solr_fq_value_range(field, range_start, range_end) click to toggle source
# File lib/filter_query.rb, line 89
def to_solr_fq_value_range(field, range_start, range_end)
  if range_start.empty?
    range_start = "*"
  end
  if range_end.empty?
    range_end = "*"
  end
  solr_value = '(' + field + ':[' + range_start + ' TO ' + range_end + '])'
  # Very important to escape the : otherwise URL.parse throws an error in Linux
  CGI.escape(solr_value)
end