def search(query, models=None): assert models and len(models) == 1, \ "This search backend only supports searching single models." model = models[0] index = get_indexer(model) table = qn(model._meta.db_table) (conv_query, fields) = convert_new(query, QueryConverter) matches = [] params = [] if conv_query: columns = ["%s.%s" % (table, qn(s)) for s in index.text] matches.append("MATCH(%s) AGAINST (%%s IN BOOLEAN MODE)" \ % ", ".join(columns)) params.append(conv_query) for (field, s) in fields.items(): if field not in index.additional: continue column = "%s.%s" % (table, qn(field)) # these fields should always just be text, so there is # no need for boolean mode matches.append("MATCH(%s) AGAINST(%%s)" % column) params.append(s) if not matches: return EmptyQuerySet(model) return index.get_query_set().extra( # TODO: this isn't an ideal solution for relevance # weighting? select={'_relevance': " + ".join(matches)}, select_params=params, where=matches, params=params, # FIXME: relevance can't be used outside extra() order_by=["-_relevance"])
def search(query, models=None): assert models and len(models) == 1, \ "This search backend only supports searching single models." model = models[0] (conv_query, fields) = convert_new(query, QueryConverter) # TODO: fields. if not conv_query: return EmptyQuerySet(model) index = get_indexer(model) if len(index.text) > 1: columns = ["coalesce(%s, '')" % qn(s) for s in index.text] else: columns = index.text # TODO: support different languages tsvector = "to_tsvector('english', %s)" % " || ".join(columns) return index.get_query_set().extra( select={'_relevance': "ts_rank(%s, to_tsquery(%%s), 32)" % tsvector}, select_params=[conv_query], where=["to_tsquery(%%s) @@ %s" % tsvector], params=[conv_query], # FIXME: relevance can't be used outside extra() order_by=["-_relevance"])
def handle_app(self, app, **options): from django.db.models import get_models from djangosearch.indexer import get_indexer for model in get_models(app): try: index = get_indexer(model) except KeyError: if self.verbosity >= 2: print "Skipping '%s' - no index" % model.__name__ continue qs = index.get_query_set().order_by(model._meta.pk.attname).select_related() total = qs.count() if self.verbosity >= 1: print "Indexing %d %s" % (total, smart_str(model._meta.verbose_name_plural)) for start in range(0, total, self.batchsize): end = min(start + self.batchsize, total) if self.verbosity >= 2: print " indexing %s - %d of %d" % (start+1, end, total) index.engine.update(index, qs[start:end])