Changeset 363

Show
Ignore:
Timestamp:
01/15/07 07:03:12 (2 years ago)
Author:
athomas
Message:

pyndexter: Fixed #26, along with adding query translation.

Files:

Legend:

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

    r361 r363  
    1212xapian = __import__('xapian') 
    1313 
     14def create_indexer(framework, path=None, stemmer='english', words=r'\w+', 
     15                   **ignore): 
     16    return XapianIndexer(framework, path=path, stemmer=stemmer, words=words) 
    1417 
    1518class XapianIndexer(Indexer): 
    16     capabilities = CAP_ORDERING | CAP_READONLY | CAP_ATTRIBUTES | \ 
    17                    CAP_RELEVANCE | CAP_HITCOUNT | CAP_LIST | CAP_WHOLEWORD | \ 
    18                    CAP_INTERSECTION 
    19  
    20     def __init__(self, stemmer='english', words=r'\w+'): 
    21         Indexer.__init__(self) 
    22         self.stemmer = xapian.Stem('english') 
     19    def __init__(self, framework, path, stemmer='english', words=r'\w+'): 
     20        Indexer.__init__(self, framework) 
     21        self.stemmer = xapian.Stem(stemmer) 
    2322        self.words = re.compile(words) 
    2423 
    25     def bind(self, framework): 
    26         Indexer.bind(self, framework) 
    27         self.path = os.path.join(framework.path, 'xapian.db') 
     24        self.path = path 
     25        self.xapian_path = os.path.join(path, 'xapian.db') 
     26        self.state_path = os.path.join(path, 'state.db') 
     27 
    2828        if self.framework.mode == READWRITE: 
    29             if not os.path.exists(self.path): 
    30                 os.makedirs(self.path) 
    31             self.db = xapian.flint_open(self.path, xapian.DB_CREATE_OR_OPEN) 
     29            if not os.path.exists(self.xapian_path): 
     30                os.makedirs(self.xapian_path) 
     31            self.db = xapian.flint_open(self.xapian_path, xapian.DB_CREATE_OR_OPEN) 
    3232        else: 
    33             self.db = xapian.flint_open(self.path) 
     33            self.db = xapian.flint_open(self.xapian_path) 
    3434 
    3535    def index(self, document): 
     
    5050        self.db.replace_document('Q' + uri, doc) 
    5151 
     52    def update(self, document): 
     53        return self.index(document) 
     54 
    5255    def discard(self, uri): 
    5356        self.db.delete_document('Q' + uri.encode('utf-8')) 
     
    5861    def close(self): 
    5962        self.sync() 
    60         self.db.close() 
     63        #self.db.close() 
    6164        self.db = None 
    6265 
    63     def search(self, phrase, flags=0, order_by=None, order_ascending=True, 
    64                order_type=str): 
    65         terms = [self.stemmer.stem_word(term.lower()
    66                  for term in self.words.findall(phrase.encode('utf-8'))] 
     66    def search(self, query): 
     67        query_parser = xapian.QueryParser() 
     68        query_parser.set_stemmer(self.stemmer
     69        query = query_parser.parse_query(self._compile_query(query)) 
    6770        enquire = xapian.Enquire(self.db) 
    68         query = xapian.Query(xapian.Query.OP_AND, terms) 
    6971        enquire.set_query(query) 
    70         return XapianSearch(self, phrase, enquire) 
     72        return XapianSearch(self, query, enquire) 
     73 
     74    def state_store(self): 
     75        return StateStore(self.state_path) 
     76 
     77    def _compile_query(self, node): 
     78        if not node or node.type == node.NULL: 
     79            return '' 
     80        if node.type == node.AND: 
     81            return '%s AND %s' % (self._compile_query(node.left), 
     82                              self._compile_query(node.right)) 
     83        elif node.type == node.OR: 
     84            return '%s OR %s' % (self._compile_query(node.left), 
     85                                 self._compile_query(node.right)) 
     86        elif node.type == node.NOT: 
     87            return 'NOT %s' % self._compile_query(node.left) 
     88        elif node.type == node.TERM: 
     89            return node.value 
     90        else: 
     91            raise NotImplementedError 
    7192 
    7293 
     
    7495    def __iter__(self): 
    7596        matches = self.context.get_mset(0, 10) 
    76         print matches.get_matches_estimated() 
    7797        for hit in matches: 
    7898            doc = hit[xapian.MSET_DOCUMENT] 
    79             uri = None 
    80             # TODO Use skip_to('Q') when implemented (see #26 for more info) 
    81             for term in doc.termlist(): 
    82                 if term[0][0] == 'Q': 
    83                     uri = term[0][1:] 
    84                     break 
     99            terms = doc.termlist() 
     100            terms.skip_to('Q') 
     101            uri = terms.next()[0][1:] 
    85102            assert uri, 'uniQue term (URI) not found in document term list' 
    86             yield Hit(uri, document=self.indexer.fetch, 
     103            yield Hit(uri, document=self.indexer.framework.fetch, 
    87104                      did=hit[xapian.MSET_DID], 
    88105                      score=float(hit[xapian.MSET_PERCENT]) / 100.0) 
     
    90107    def __len__(self): 
    91108        return len(self.context) 
    92  
    93 #    def __getitem__(self, index): 
    94 #        doc = self.indexer.idx.get_document(self.context[index]['uid']) 
    95 #        return Hit(doc.get_value(self.indexer.idx.indexValueMap['uri']), 
    96 #                   document=self.indexer.fetch)