예제 #1
0
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"])
예제 #2
0
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"])
예제 #3
0
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"])
예제 #4
0
    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])