require 'rsi/logmanager' module RSI class Query include Loggable def initialize() @subqueries = [] end def add_subquery( query ) @subqueries << query end def evaluate( locator ); end end class ANDQuery < Query def evaluate( locator ) ret_set = nil @subqueries.each do |q| set = q.evaluate( locator ) if ret_set.nil? ret_set = set else ret_set = ret_set & set end # short-circuit bottoming out if ret_set.size()==0 return ret_set end end return ret_set end def to_s return "( " + @subqueries.join(" AND ") + " )"; end end class ORQuery < Query def evaluate() ret_set = [] @subqueries.each do |q| ret_set = ret_set | q.evaluate( locator ) end return ret_set end def to_s return "( " + @subqueries.join(" OR ") + " )"; end end class TermQuery < Query attr_accessor :field, :term def initialize( field, term ) @field = field @term = term end def evaluate( locator ) logger.debug( "Getting dict for #@field" ) dict = locator.get_dict_for_field( @field ) # get all docids containing @field:@term -> [] # return set unless dict.has_term?( term ) logger.debug( "Dict has no such term #{term}" ) return [] else ret = [] termid = dict.get_termid_for( term ) logger.debug( "Getting entries for #{term}(#{termid})" ) dict.get_entry_list( termid ).each do |termentry| logger.debug( termentry.to_s ) ret << termentry.docid end return ret.uniq end end def to_s return "#@field='#@term'" end end ##; def analyze_query( q_str ) ##; # (a OR b) AND (c OR d) ##; # -> AND[ OR[a,b], OR[c,d] ] ##; # split on whitespace ##; # split x:foo ##; # tokenize foo ##; # add another AND termquery ##; ##; end end