Class: Ferret::Search::MultiPhraseQuery

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

Overview

MultiPhraseQuery is a generalized version of PhraseQuery, with an added method #add(Term[]).

To use this class, to search for the phrase “Microsoft app*” first use add(Term) on the term “Microsoft”, then find all terms that have “app” as prefix using IndexReader.terms(Term), and use MultiPhraseQuery.add(Term[] terms) to add them to the query.

Author Anders Nielsen

Defined Under Namespace

Classes: MultiPhraseWeight

Instance Attribute Summary collapse

Attributes inherited from Query

#boost

Instance Method Summary collapse

Methods inherited from Query

#combine, #extract_terms, #merge_boolean_queries, #similarity, #weight

Constructor Details

#initializeMultiPhraseQuery

Returns a new instance of MultiPhraseQuery.



17
18
19
20
21
22
23
# File 'lib/ferret/search/multi_phrase_query.rb', line 17

def initialize()
  super()
  @slop = 0
  @term_arrays = []
  @positions = []
  @field = nil
end

Instance Attribute Details

#fieldObject (readonly)

Returns the value of attribute field.



15
16
17
# File 'lib/ferret/search/multi_phrase_query.rb', line 15

def field
  @field
end

#positionsObject (readonly)

Returns the value of attribute positions.



15
16
17
# File 'lib/ferret/search/multi_phrase_query.rb', line 15

def positions
  @positions
end

#slopObject

Returns the value of attribute slop.



14
15
16
# File 'lib/ferret/search/multi_phrase_query.rb', line 14

def slop
  @slop
end

#term_arraysObject (readonly)

Returns the value of attribute term_arrays.



15
16
17
# File 'lib/ferret/search/multi_phrase_query.rb', line 15

def term_arrays
  @term_arrays
end

Instance Method Details

#add(terms, position = nil, pos_inc = 1) ⇒ Object Also known as: <<

Allows to specify the relative position of terms within the phrase.

See PhraseQuery#add(Term, int)

terms

the array of terms to search for or a single term

position

the position to search for these terms



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ferret/search/multi_phrase_query.rb', line 30

def add(terms, position = nil, pos_inc = 1) 
  if position.nil?
    position = (@positions.size > 0) ? (@positions[-1] + pos_inc) : 0
  end

  if terms.instance_of?(Term)
    terms = [terms]
  end

  if (@term_arrays.size == 0)
    @field = terms[0].field
  end

  terms.each do |term|
    if (term.field != @field) 
      raise ArgumentError,
        "All phrase terms must be in the same field (#{@field}): #{term}"
    end
  end

  @term_arrays << terms
  @positions << position
end

#create_weight(searcher) ⇒ Object



179
180
181
# File 'lib/ferret/search/multi_phrase_query.rb', line 179

def create_weight(searcher)
  return MultiPhraseWeight.new(self, searcher)
end

#rewrite(reader) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/ferret/search/multi_phrase_query.rb', line 165

def rewrite(reader) 
  if (@term_arrays.size() == 1) # optimize one-term case
    terms = @term_arrays[0]
    bq = BooleanQuery.new(true)
    terms.each do |term|
      bq.add(TermQuery.new(term), BooleanClause::Occur::SHOULD)
    end
    bq.boost = boost()
    return boq
  else 
    return self
  end
end

#to_s(f = nil) ⇒ Object

Prints a user-readable version of this query.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/ferret/search/multi_phrase_query.rb', line 184

def to_s(f = nil) 
  buffer = ""
  buffer << "#{@field}:" if @field != f 
  buffer << '"'
  last_pos = -1
  @term_arrays.each_index do |i|
    terms = @term_arrays[i]
    pos = @positions[i]
    last_pos.upto(pos-2) {buffer << "<> "}
    last_pos = pos
    buffer << "#{terms.map {|term| term.text}.join("|")} "
  end
  buffer.rstrip!
  buffer << '"'

  buffer << "~#{@slop}" if (@slop != 0) 
  buffer << "^#{boost()}" if boost() != 1.0
  return buffer
end