Changeset 371
- Timestamp:
- 02/04/07 04:19:22 (2 years ago)
- Files:
-
- pyndexter/branches/refactoring/pyndexter/indexers/hype.py (modified) (2 diffs)
- pyndexter/branches/refactoring/pyndexter/indexers/hyperestraier.py (modified) (2 diffs)
- pyndexter/branches/refactoring/pyndexter/indexers/lucene.py (modified) (2 diffs)
- pyndexter/branches/refactoring/pyndexter/indexers/xapian.py (modified) (2 diffs)
- pyndexter/branches/refactoring/pyndexter/__init__.py (modified) (2 diffs)
- pyndexter/branches/refactoring/pyndexter/util.py (modified) (1 diff)
- pyndexter/branches/refactoring/.todo (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pyndexter/branches/refactoring/pyndexter/indexers/hype.py
r367 r371 53 53 54 54 def search(self, query): 55 query = self._compile_query(query).decode('utf-8')55 query = query.to_boolean(not_='!').decode('utf-8') 56 56 search = self.db.search(query) 57 57 # if order is not None: … … 70 70 def state_store(self): 71 71 return StateStore(self.state_path) 72 73 # Internal methods74 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.value87 else:88 raise NotImplementedError89 72 90 73 pyndexter/branches/refactoring/pyndexter/indexers/hyperestraier.py
r369 r371 62 62 63 63 def search(self, query): 64 phrase = self._compile_query(query)64 phrase = query.to_boolean(not_='!') 65 65 return self.hype_search(phrase, simple=False) 66 66 … … 84 84 # search = search.order(order) 85 85 return HyperestraierResult(self, search) 86 87 # Internal methods88 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.value101 else:102 raise NotImplementedError103 86 104 87 pyndexter/branches/refactoring/pyndexter/indexers/lucene.py
r367 r371 37 37 38 38 def search(self, query): 39 query = self._compile_query(query)39 query = query.to_boolean() 40 40 query = PyLucene.QueryParser.parse(query, 'title', analyzer) 41 41 raise query … … 53 53 return StateStore(self.store_path) 54 54 55 # Internal methods56 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.value69 else:70 raise NotImplementedError71 72 55 73 56 class LuceneResult(Result): pyndexter/branches/refactoring/pyndexter/indexers/xapian.py
r370 r371 77 77 query_parser = xapian.QueryParser() 78 78 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()) 80 80 enquire = xapian.Enquire(self.db) 81 81 enquire.set_query(query) … … 84 84 def state_store(self): 85 85 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.value100 else:101 raise NotImplementedError102 86 103 87 pyndexter/branches/refactoring/pyndexter/__init__.py
r367 r371 409 409 raise InvalidQuery('Expected terminal, got "%s"' % tokens[0][1]) 410 410 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 411 443 # Internal methods 412 444 def _tokenise(self, phrase): … … 430 462 for token in self._tokenise_re.finditer(phrase)] 431 463 return tokens 464 432 465 433 466 class StateStore(object): pyndexter/branches/refactoring/pyndexter/util.py
r367 r371 14 14 except: 15 15 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 = size22 self.data = {}23 self.accessbykey = {}24 self.accessbytime = {}25 26 def __setitem__(self, key, value):27 self.data[key] = value28 self._update_cache(key)29 30 def __getitem__(self, key):31 value = self.data[key]32 self._update_cache(key)33 return value34 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 methods45 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] = t50 self.accessbytime[t] = key51 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]58 16 59 17 pyndexter/branches/refactoring/.todo
r369 r371 36 36 Add slicing to Result objects. This will allow fast pagination in result displays. 37 37 </note> 38 <note priority="low" time="1168875038" >38 <note priority="low" time="1168875038" done="1170587379"> 39 39 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> 40 43 </note> 41 44 <note priority="medium" time="1169007320">
