Changeset 371

Show
Ignore:
Timestamp:
02/04/07 04:19:22 (2 years ago)
Author:
athomas
Message:

pyndexter: Using a generic Query.to_boolean() method to convert Query
objects to Indexer specific syntax.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pyndexter/branches/refactoring/pyndexter/indexers/hype.py

    r367 r371  
    5353 
    5454    def search(self, query): 
    55         query = self._compile_query(query).decode('utf-8') 
     55        query = query.to_boolean(not_='!').decode('utf-8') 
    5656        search = self.db.search(query) 
    5757#        if order is not None: 
     
    7070    def state_store(self): 
    7171        return StateStore(self.state_path) 
    72  
    73     # Internal methods 
    74     def _compile_query(self, node): 
    75         if not node or node.type == node.NULL: 
    76             return '' 
    77         if node.type == node.AND: 
    78             return '%s AND %s' % (self._compile_query(node.left), 
    79                                   self._compile_query(node.right)) 
    80         elif node.type == node.OR: 
    81             return '%s OR %s' % (self._compile_query(node.left), 
    82                                  self._compile_query(node.right)) 
    83         elif node.type == node.NOT: 
    84             return 'NOT %s' % self._compile_query(node.left) 
    85         elif node.type == node.TERM: 
    86             return node.value 
    87         else: 
    88             raise NotImplementedError 
    8972 
    9073 
  • pyndexter/branches/refactoring/pyndexter/indexers/hyperestraier.py

    r369 r371  
    6262 
    6363    def search(self, query): 
    64         phrase = self._compile_query(query
     64        phrase = query.to_boolean(not_='!'
    6565        return self.hype_search(phrase, simple=False) 
    6666 
     
    8484#            search = search.order(order) 
    8585        return HyperestraierResult(self, search) 
    86  
    87     # Internal methods 
    88     def _compile_query(self, node): 
    89         if not node or node.type == node.NULL: 
    90             return '' 
    91         if node.type == node.AND: 
    92             return '%s AND %s' % (self._compile_query(node.left), 
    93                               self._compile_query(node.right)) 
    94         elif node.type == node.OR: 
    95             return '%s OR %s' % (self._compile_query(node.left), 
    96                                  self._compile_query(node.right)) 
    97         elif node.type == node.NOT: 
    98             return '!%s' % self._compile_query(node.left) 
    99         elif node.type == node.TERM: 
    100             return node.value 
    101         else: 
    102             raise NotImplementedError 
    10386 
    10487 
  • pyndexter/branches/refactoring/pyndexter/indexers/lucene.py

    r367 r371  
    3737 
    3838    def search(self, query): 
    39         query = self._compile_query(query
     39        query = query.to_boolean(
    4040        query = PyLucene.QueryParser.parse(query, 'title', analyzer) 
    4141        raise query 
     
    5353        return StateStore(self.store_path) 
    5454 
    55     # Internal methods 
    56     def _compile_query(self, node): 
    57         if not node or node.type == node.NULL: 
    58             return '' 
    59         if node.type == node.AND: 
    60             return '%s AND %s' % (self._compile_query(node.left), 
    61                                   self._compile_query(node.right)) 
    62         elif node.type == node.OR: 
    63             return '%s OR %s' % (self._compile_query(node.left), 
    64                                  self._compile_query(node.right)) 
    65         elif node.type == node.NOT: 
    66             return 'NOT %s' % self._compile_query(node.left) 
    67         elif node.type == node.TERM: 
    68             return node.value 
    69         else: 
    70             raise NotImplementedError 
    71  
    7255 
    7356class LuceneResult(Result): 
  • pyndexter/branches/refactoring/pyndexter/indexers/xapian.py

    r370 r371  
    7777        query_parser = xapian.QueryParser() 
    7878        query_parser.set_stemmer(self.stemmer) 
    79         query = query_parser.parse_query(self._compile_query(query)) 
     79        query = query_parser.parse_query(query.to_boolean()) 
    8080        enquire = xapian.Enquire(self.db) 
    8181        enquire.set_query(query) 
     
    8484    def state_store(self): 
    8585        return StateStore(self.state_path) 
    86  
    87     def _compile_query(self, node): 
    88         if not node or node.type == node.NULL: 
    89             return '' 
    90         if node.type == node.AND: 
    91             return '%s AND %s' % (self._compile_query(node.left), 
    92                                   self._compile_query(node.right)) 
    93         elif node.type == node.OR: 
    94             return '%s OR %s' % (self._compile_query(node.left), 
    95                                  self._compile_query(node.right)) 
    96         elif node.type == node.NOT: 
    97             return 'NOT %s' % self._compile_query(node.left) 
    98         elif node.type == node.TERM: 
    99             return node.value 
    100         else: 
    101             raise NotImplementedError 
    10286 
    10387 
  • pyndexter/branches/refactoring/pyndexter/__init__.py

    r367 r371  
    409409        raise InvalidQuery('Expected terminal, got "%s"' % tokens[0][1]) 
    410410 
     411    def to_boolean(self, and_=' AND ', or_=' OR ', not_='NOT '): 
     412        """Convert Query to a boolean expression. Useful for indexers with 
     413        "typical" boolean query syntaxes. 
     414 
     415        eg. "term AND term OR term AND NOT term" 
     416 
     417        The expanded operators can be customised for syntactical variations. 
     418 
     419        >>> Query('foo bar').to_boolean() 
     420        'foo AND bar' 
     421        >>> Query('foo bar or baz').to_boolean() 
     422        'foo AND bar OR baz' 
     423        >>> Query('foo -bar or baz').to_boolean() 
     424        'foo AND NOT bar OR baz' 
     425        """ 
     426        def _convert(node): 
     427            if not node or node.type == node.NULL: 
     428                return '' 
     429            if node.type == node.AND: 
     430                return '%s%s%s' % (_convert(node.left), and_, 
     431                                   _convert(node.right)) 
     432            elif node.type == node.OR: 
     433                return '%s%s%s' % (_convert(node.left), or_, 
     434                                   _convert(node.right)) 
     435            elif node.type == node.NOT: 
     436                return '%s%s' % (not_, _convert(node.left)) 
     437            elif node.type == node.TERM: 
     438                return node.value 
     439            else: 
     440                raise NotImplementedError 
     441        return _convert(self) 
     442 
    411443    # Internal methods 
    412444    def _tokenise(self, phrase): 
     
    430462                  for token in self._tokenise_re.finditer(phrase)] 
    431463        return tokens 
     464 
    432465 
    433466class StateStore(object): 
  • pyndexter/branches/refactoring/pyndexter/util.py

    r367 r371  
    1414except: 
    1515    from sets import Set as set 
    16  
    17  
    18 class CacheDict(DictMixin): 
    19     """ A caching dictionary, with a bounded size. """ 
    20     def __init__(self, size): 
    21         self.size = size 
    22         self.data = {} 
    23         self.accessbykey = {} 
    24         self.accessbytime = {} 
    25  
    26     def __setitem__(self, key, value): 
    27         self.data[key] = value 
    28         self._update_cache(key) 
    29  
    30     def __getitem__(self, key): 
    31         value = self.data[key] 
    32         self._update_cache(key) 
    33         return value 
    34  
    35     def __delitem__(self, key): 
    36         age = self.accessbykey[key] 
    37         del self.accessbytime[age] 
    38         del self.accessbykey[key] 
    39         del self.data[key] 
    40  
    41     def keys(self): 
    42         return self.data.keys() 
    43  
    44     # Internal methods 
    45     def _update_cache(self, key): 
    46         t = time.time() 
    47         if key in self.accessbykey: 
    48             del self.accessbytime[self.accessbykey[key]] 
    49         self.accessbykey[key] = t 
    50         self.accessbytime[t] = key 
    51         if len(self.accessbykey) >= self.size: 
    52             oldest = self.accessbytime.keys() 
    53             oldest.sort() 
    54             oldest = oldest[:self.size / 2] 
    55             for age in oldest: 
    56                 key = self.accessbytime[age] 
    57                 del self[key] 
    5816 
    5917 
  • pyndexter/branches/refactoring/.todo

    r369 r371  
    3636        Add slicing to Result objects. This will allow fast pagination in result displays. 
    3737    </note> 
    38     <note priority="low" time="1168875038"
     38    <note priority="low" time="1168875038" done="1170587379"
    3939        Add some "stock" query translators (eg. a AND b OR c style, a b or c, +a +b c, etc.) 
     40        <comment> 
     41            Added a general to_boolean() method to the Query object. Operators can be overridden for variants. 
     42        </comment> 
    4043    </note> 
    4144    <note priority="medium" time="1169007320">