Class: ParsingNesting::Tree::OrList

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

Instance Attribute Summary

Attributes inherited from List

#list

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)


262
263
264
# File 'lib/parsing_nesting/tree.rb', line 262

def can_embed?
  false
end

#negateObject

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



327
328
329
# File 'lib/parsing_nesting/tree.rb', line 327

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

#to_multi_queries(local_params) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/parsing_nesting/tree.rb', line 312

def to_multi_queries(local_params)      
  "( " + 
    list.collect do |i|
    if i.kind_of?(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.



308
309
310
# File 'lib/parsing_nesting/tree.rb', line 308

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

#to_query(local_params) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/parsing_nesting/tree.rb', line 267

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.kind_of?(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)



293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/parsing_nesting/tree.rb', line 293

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. 
  return 'NOT _query_:"' + 
      bs_escape(build_local_params(solr_params) + 
      embeddables.collect {|n| n.to_embed}.join(" ")) + 
    '"'
end