Class: ParsingNesting::Tree::OrList

Inherits:
List show all
Defined in:
lib/parsing_nesting/tree.rb

Instance Attribute Summary

Attributes inherited from List

#list, #query_parser

Instance Method Summary collapse

Methods inherited from List

#initialize, #simple_pure_negative?, #to_single_query_params

Constructor Details

This class inherits a constructor from ParsingNesting::Tree::List

Instance Method Details

#can_embed?Boolean

never embeddable

Returns:

  • (Boolean)


256
257
258
# File 'lib/parsing_nesting/tree.rb', line 256

def can_embed?
  false
end

#negateObject

convenient logical property here, not(a OR b) === not(a) AND not(b)



320
321
322
# File 'lib/parsing_nesting/tree.rb', line 320

def negate
  AndList.new(list.collect { |n| n.negate })
end

#to_multi_queries(local_params) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/parsing_nesting/tree.rb', line 305

def to_multi_queries(local_params)
  "( " +
    list.collect do |i|
      if i.is_a?(NotExpression) || (i.respond_to?(:simple_pure_negative?) && i.simple_pure_negative?)
        # need special handling to work around Solr 1.4.1's lack of handling
        # of pure negative in an OR
        "(*:* AND #{i.to_query(local_params)})"
      else
        i.to_query(local_params)
        end
    end.join(" OR ") +
   " )"
end

#to_one_dismax_query(local_params) ⇒ Object

all our arguments are ‘simple’ (terms and phrases with +/-), put am all in one single dismax with mm forced to 1.



301
302
303
# File 'lib/parsing_nesting/tree.rb', line 301

def to_one_dismax_query(local_params)
  build_nested_query(list, local_params.merge(:mm => "1"))
end

#to_query(local_params) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/parsing_nesting/tree.rb', line 260

def to_query(local_params)
  # Okay, we're never embeddable as such, but sometimes we can
  # turn our operands into one single nested dismax query with mm=1, when
  # all our operands are 'simple', other times we need to actually do
  # two seperate nested queries seperated by lucene OR.
  # If all our children are embeddable but _not_ an "AndList", we can
  # do the one query part. The AndList is theoretically embeddable, but
  # not in a way compatible with flattening an OR to one query.
  # Sorry, this part is one of the least clean part of this code!

  not_flattenable = list.find { |i| !(i.can_embed? && !i.is_a?(AndList)) }

  if not_flattenable
    to_multi_queries(local_params)
  elsif simple_pure_negative?
    to_simple_pure_negative_query(local_params)
  else
    to_one_dismax_query(local_params)
  end
end

#to_simple_pure_negative_query(local_params) ⇒ Object

build_nested_query isn’t smart enough to handle refactoring a simple pure negative “OR”, that needs an mm of 100%. Let’s just do it ourselves. What we’re doing makes more sense if you remember that: -a OR -b === NOT (a AND b)



286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/parsing_nesting/tree.rb', line 286

def to_simple_pure_negative_query(local_params)
  # take em out of their ExcludedClauses
  embeddables = list.collect { |n| n.operand }
  # and insist on mm 100%
  solr_params = local_params.merge(:mm => "100%")

  # and put the NOT in front to preserve semantics.
  'NOT _query_:"' +
      bs_escape(build_local_params(solr_params) +
      embeddables.collect { |n| n.to_embed }.join(" ")) +
    '"'
end