We are doing a site search where we search a field with an icontains
. It's working great, but the results that come up dont have the most relevant result at the top.
An example is searching for "Game of Thrones". If the search is "Game of", the first result could be "Crazy Game of..." and the second is "Game of Thrones"
Essentially, I'd like to search with icontains
, but order by startswith
. Any ideas?
Django added new features since this question was asked, and now handles this use case natively.
You can order results by an arbitrary comparison using the following features in Django's QuerySet API:
Q()
Object: encapsulates a reusable query expression. Our expression compares the object's field against our "Game of" search value.ExressionWrapper()
: wraps a query expression, in order to control the ModelField
type with output_field
. In this case, the type is a Boolean.annotate()
: dynamically add a ModelField
to each QuerySet object, based on the result of a query expression. We want to add a True
/False
field to sort on.order_by()
: order the QuerySet objects by specified fields. We want to order by the annotated field value, in reverse, so that True
values are displayed first.
from django.db.model import Q, ExpressionWrapper, BooleanField
....
# Your original setup.
search_term = 'Game of'
data = MyModel.objects.filter(name__icontains=search_term)
# Encapsulate the comparison expression.
expression = Q(name__startswith=search_term)
# Wrap the expression to specify the field type.
is_match = ExpressionWrapper(expression, output_field=BooleanField())
# Annotate each object with the comparison.
data = data.annotate(my_field=is_match)
# Order by the annotated field in reverse, so `True` is first (0 < 1).
data = data.order_by('-my_field')
....
The ordering you're describing is subjective and there's no data like that that comes out of the database (that I'm aware of). If a feature like this is important, you might want to look into a search engine like Solr or Sphinx where you can configure how relevancy scores are determined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With