Class: Ferret::Search::RangeFilter

Inherits:
Filter
  • Object
show all
Includes:
Index
Defined in:
lib/ferret/search/range_filter.rb

Overview

A Filter that restricts search results to a range of values in a given field.

This code borrows heavily from RangeQuery, but is implemented as a Filter.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(field_name, lower_term, upper_term, include_lower, include_upper) ⇒ RangeFilter

field_name

The field this range applies to

lower_term

The lower bound on this range

upper_term

The upper bound on this range

include_lower

Does this range include the lower bound?

include_upper

Does this range include the upper bound?



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ferret/search/range_filter.rb', line 14

def initialize(field_name, lower_term, upper_term, include_lower, include_upper) 
  @field_name = field_name
  @lower_term = lower_term
  @upper_term = upper_term
  @include_lower = include_lower
  @include_upper = include_upper
  
  if (lower_term.nil? and upper_term.nil?) 
    raise ArgumentError, "At least one value must be non-nil"
  end
  if (include_lower and lower_term.nil?) 
    raise ArgumentError, "The lower bound must be non-nil to be inclusive"
  end
  if (include_upper and upper_term.nil?) 
    raise ArgumentError, "The upper bound must be non-nil to be inclusive"
  end
  if (upper_term and lower_term and upper_term < lower_term)
    raise ArgumentError, "The lower bound must less than the upper bound"
  end
end

Class Method Details

.new_less(field_name, upper_term, include_upper = true) ⇒ Object

Constructs a filter for field field_name matching less than or equal to upper_term.



37
38
39
# File 'lib/ferret/search/range_filter.rb', line 37

def RangeFilter.new_less(field_name, upper_term, include_upper = true) 
  return RangeFilter.new(field_name, nil, upper_term, false, include_upper)
end

.new_more(field_name, lower_term, include_lower = true) ⇒ Object

Constructs a filter for field field_name matching greater than or equal to lower_term.



43
44
45
# File 'lib/ferret/search/range_filter.rb', line 43

def RangeFilter.new_more(field_name, lower_term, include_lower = true) 
  return RangeFilter.new(field_name, lower_term, nil, include_lower, false)
end

Instance Method Details

#bits(reader) ⇒ Object

Returns a BitVector with true for documents which should be permitted in search results, and false for those that should not.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ferret/search/range_filter.rb', line 49

def bits(reader)
  bits = Ferret::Utils::BitVector.new()
  term_enum = reader.terms_from(Term.new(@field_name, @lower_term||""))
  
  begin 
    if (term_enum.term() == nil) 
      return bits
    end
    check_lower = !@include_lower # make adjustments to set to exclusive
  
    term_docs = reader.term_docs
    begin 
      begin 
        term = term_enum.term()
        break if (term.nil? or term.field != @field_name) 

        if (!check_lower or @lower_term.nil? or term.text > @lower_term) 
          check_lower = false
          if @upper_term
            compare = @upper_term <=> term.text
            # if beyond the upper term, or is exclusive and
            # this is equal to the upper term, break out 
            if ((compare < 0) or (!@include_upper and compare == 0))
              break
            end
          end
          # we have a good term, find the docs 
          
          term_docs.seek(term_enum)
          while term_docs.next?
            bits.set(term_docs.doc)
          end
        end
      end while term_enum.next?
    ensure 
      term_docs.close()
    end
  ensure 
    term_enum.close()
  end

  return bits
end

#to_sObject



93
94
95
96
97
98
99
100
101
# File 'lib/ferret/search/range_filter.rb', line 93

def to_s() 
  buffer = "#{@field_name}:"
  buffer << "[" if @include_lower
  buffer << @lower_term if @lower_term
  buffer << "-"
  buffer << @upper_term if @upper_term
  buffer << @include_upper ? "]" : "end"
  return buffer
end