[Solved]-How to use a tsvector field to perform ranking in Django with postgresql full-text search?

17👍

If your model has a SearchVectorField like so:

from django.contrib.postgres.search import SearchVectorField

class Entry(models.Model):
    ...
    search_vector = SearchVectorField()

you would use the F expression:

from django.db.models import F

...
Entry.objects.annotate(
    rank=SearchRank(F('search_vector'), query)
).order_by('-rank')
👤Nad

0👍

I’ve been seeing mixed answers here on SO and in the official documentation. F Expressions aren’t used in the documentation for this. However it may just be that the documentation doesn’t actually provide an example for using SearchRank with a SearchVectorField.

Looking at the output of .explain(analyze=True) :

Without the F Expression:

Sort Key: (ts_rank(to_tsvector(COALESCE((search_vector)::text, ''::text)) 

When the F Expression is used:

Sort Key: (ts_rank(search_vector, ...) 

In my experience, it seems the only difference between using an F Expression and the field name in quotes is that using the F Expression returns much faster, but is sometimes less accurate – depending on how you structure the query – it can be useful to enforce it with a COALESCE in some cases. In my case it’s about a 3-5x speedboost to use the F Expression with my SearchVectorField.

Ensuring your SearchQuery has a config kwarg also improves things dramatically.

👤lys

Leave a comment