def search(self, q, models=None, order_by=RELEVANCE, limit=None, offset=None): """Perform a search.""" original_query = q q = query.convert(original_query, LuceneQueryConverter) if models: models_queries = [] for m in models: if hasattr(m, "_meta"): models_queries.append('%s:"%s"' % (MODEL_FIELD, m._meta)) else: models_queries.append('%s:"%s"' % (MODEL_FIELD, m)) q += ' AND (%s)' % (' '.join(models_queries)) searcher = PyLucene.IndexSearcher(settings.SEARCH_INDEX_PATH) analyzer = PorterStemmerAnalyzer() compiled_query = PyLucene.QueryParser(CONTENTS_FIELD, analyzer).parse(q) if order_by is RELEVANCE: sort = PyLucene.Sort.RELEVANCE else: reversed = order_by.startswith('-') sort_field = PyLucene.SortField(order_by.lstrip('-'), reversed) sort = PyLucene.Sort(sort_field) hits = searcher.search(compiled_query, sort) return self._get_search_results(original_query, hits, limit, offset)
def search(self, phrase, keywords=None, sortAscending=True): if not phrase and not keywords: return [] # XXX Colons in phrase will screw stuff up. Can they be quoted or # escaped somehow? Probably by using a different QueryParser. if keywords: fieldPhrase = u' '.join(u':'.join((k, v)) for (k, v) in keywords.iteritems()) if phrase: phrase = phrase + u' ' + fieldPhrase else: phrase = fieldPhrase phrase = phrase.translate({ ord(u'@'): u' ', ord(u'-'): u' ', ord(u'.'): u' ' }) qp = PyLucene.QueryParser('text', self.analyzer) qp.setDefaultOperator(qp.Operator.AND) query = qp.parseQuery(phrase) sort = PyLucene.Sort(PyLucene.SortField('sortKey', not sortAscending)) try: hits = self.searcher.search(query, sort) except PyLucene.JavaError, err: if 'no terms in field sortKey' in str(err): hits = [] else: raise