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"])