Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order Query results by startswith match

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?

like image 238
Brenden Avatar asked Feb 20 '23 18:02

Brenden


2 Answers

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:

  1. Q() Object: encapsulates a reusable query expression. Our expression compares the object's field against our "Game of" search value.
  2. ExressionWrapper(): wraps a query expression, in order to control the ModelField type with output_field. In this case, the type is a Boolean.
  3. 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.
  4. 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')

    ....
like image 60
HuntedCodes Avatar answered Mar 05 '23 17:03

HuntedCodes


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.

like image 44
Chris Forrette Avatar answered Mar 05 '23 17:03

Chris Forrette