Class: Ferret::Search::BooleanQuery

Inherits:
Query
  • Object
show all
Defined in:
lib/ferret/search/boolean_query.rb

Overview

A Query that matches documents matching boolean combinations of other queries, e.g. TermQuerys, PhraseQuerys or other BooleanQuerys.

Defined Under Namespace

Classes: BooleanWeight, TooManyClauses

Constant Summary collapse

DEFAULT_MAX_CLAUSE_COUNT =
1024
@@max_clause_count =
DEFAULT_MAX_CLAUSE_COUNT

Instance Attribute Summary collapse

Attributes inherited from Query

#boost

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Query

#merge_boolean_queries, #weight

Constructor Details

#initialize(coord_disabled = false) ⇒ BooleanQuery

Constructs an empty boolean query.

Similarity#coord(int,int) may be disabled in scoring, as appropriate. For example, this score factor does not make sense for most automatically generated queries, like WildcardQuery and FuzzyQuery.

coord_disabled

disables Similarity#coord(int,int) in scoring.



43
44
45
46
47
# File 'lib/ferret/search/boolean_query.rb', line 43

def initialize(coord_disabled = false) 
  super()
  @coord_disabled = coord_disabled
  @clauses = []
end

Instance Attribute Details

#clausesObject

Returns the value of attribute clauses.



19
20
21
# File 'lib/ferret/search/boolean_query.rb', line 19

def clauses
  @clauses
end

#max_clause_countObject

The maximum number of clauses permitted. Default value is 1024.

TermQuery clauses are generated from for example prefix queries and fuzzy queries. Each TermQuery needs some buffer space during search, so this parameter indirectly controls the maximum buffer requirements for query search.

When this parameter becomes a bottleneck for a Query one can use a Filter. For example instead of a RangeQuery one can use a RangeFilter.

Attempts to add more than the permitted number of clauses cause TooManyClauses to be raisen.



18
19
20
# File 'lib/ferret/search/boolean_query.rb', line 18

def max_clause_count
  @max_clause_count
end

Class Method Details

.max_clause_countObject



23
24
25
# File 'lib/ferret/search/boolean_query.rb', line 23

def BooleanQuery.max_clause_count
  return @@max_clause_count
end

.max_clause_count=(mcc) ⇒ Object



26
27
28
# File 'lib/ferret/search/boolean_query.rb', line 26

def BooleanQuery.max_clause_count=(mcc)
  @@max_clause_count = mcc
end

Instance Method Details

#add_clause(clause) ⇒ Object Also known as: <<

Adds a clause to a boolean query.

raises

TooManyClauses if the new number of clauses exceeds the maximum clause number. See #max_clause_count()



92
93
94
95
96
97
98
# File 'lib/ferret/search/boolean_query.rb', line 92

def add_clause(clause) 
  if @clauses.size >= @@max_clause_count
    raise TooManyClauses
  end

  @clauses << clause
end

#add_query(query, occur) ⇒ Object

Adds a clause to a boolean query. Clauses may be:

required

which means that documents which _do not_ match this sub-query will not match the boolean query

prohibited

which means that documents which do match this sub-query will not match the boolean query; or

neither

in which case matched documents are neither prohibited from nor required to match the sub-query. However, a document must match at least 1 sub-query to match the boolean query.

  • For required use add(query, BooleanClause::Occur::MUST)

  • For prohibited use add(query, BooleanClause::Occur::MUST_NOT)

  • For neither use add(query, BooleanClause::Occur::SHOULD)

raises

TooManyClauses if the new number of clauses exceeds the maximum clause number #max_clause_count()



85
86
87
# File 'lib/ferret/search/boolean_query.rb', line 85

def add_query(query, occur) 
  add_clause(BooleanClause.new(query, occur))
end

#combine(queries) ⇒ Object



250
251
252
# File 'lib/ferret/search/boolean_query.rb', line 250

def combine(queries) 
  return Query.merge_boolean_queries(queries)
end

#coord_disabled?Boolean

Returns true iff Similarity#coord(int,int) is disabled in scoring for this query instance. See #BooleanQuery(boolean)

Returns:

  • (Boolean)


52
53
54
# File 'lib/ferret/search/boolean_query.rb', line 52

def coord_disabled?()
  return @coord_disabled
end

#create_weight(searcher) ⇒ Object

end BooleanWeight



207
208
209
# File 'lib/ferret/search/boolean_query.rb', line 207

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

#eql?(other) ⇒ Boolean Also known as: ==

Returns true iff o is equal to this.

Returns:

  • (Boolean)


289
290
291
292
293
294
# File 'lib/ferret/search/boolean_query.rb', line 289

def eql?(other) 
  if not other.instance_of?(BooleanQuery)
    return false
  end
  return (boost() == other.boost() and @clauses == other.clauses)
end

#extract_terms(terms) ⇒ Object



244
245
246
247
248
# File 'lib/ferret/search/boolean_query.rb', line 244

def extract_terms(terms) 
  @clauses.each do |clause|
    clause.query.extract_terms(terms)
  end
end

#hashObject

Returns a hash code value for this object.



298
299
300
# File 'lib/ferret/search/boolean_query.rb', line 298

def hash() 
  return boost().hash ^ @clauses.hash
end

#initialize_copy(o) ⇒ Object



254
255
256
257
# File 'lib/ferret/search/boolean_query.rb', line 254

def initialize_copy(o)
  super
  @clauses = o.clauses.clone
end

#rewrite(reader) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/ferret/search/boolean_query.rb', line 211

def rewrite(reader)
  if @clauses.size == 1 # optimize 1-clause queries
    clause = @clauses[0]
    if not clause.prohibited? # just return clause

      query = clause.query.rewrite(reader) # rewrite first

      if boost() != 1.0 # incorporate boost
        if query == clause.query # if rewrite was no-op
          query = query.clone    # then clone before boost
        end
        query.boost = boost() * query.boost()
      end

      return query
    end
  end

  clone = nil # recursively rewrite
  @clauses.each_with_index do |clause, i|
    query = clause.query().rewrite(reader)
    if query != clause.query() # clause rewrote: must clone
      clone ||= clone()
      clone.clauses[i] = BooleanClause.new(query, clause.occur)
    end
  end
  if (clone != nil) 
    return clone # some clauses rewrote
  else
    return self  # no clauses rewrote
  end
end

#similarity(searcher) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ferret/search/boolean_query.rb', line 56

def similarity(searcher) 
  sim = super
  if (@coord_disabled) # disable coord as requested
    class <<sim 
      def coord(overlap, max_overlap) 
        return 1.0
      end
    end
  end
  return sim
end

#to_s(field = nil) ⇒ Object

Prints a user-readable version of this query.



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/ferret/search/boolean_query.rb', line 260

def to_s(field = nil) 
  buffer = ""
  buffer << "(" if boost != 1.0

  @clauses.each_with_index do |clause, i|
    if clause.prohibited?
      buffer << "-"
    elsif clause.required?
      buffer << "+"
    end

    sub_query = clause.query
    if sub_query.instance_of? BooleanQuery # wrap sub-bools in parens
      buffer << "(#{clause.query.to_s(field)})"
    else
      buffer << clause.query.to_s(field)
    end

    if i != (@clauses.size - 1)
      buffer << " "
    end
  end

  buffer << ")^#{boost}" if boost() != 1.0 

  return buffer
end