Sort the Django queryset by priority

3

I'm creating a search engine on my platform. I do a search for content title, description and tags inside it. Here is the code:

questions = Question.objects.filter(reduce(lambda x, y: x | y, [(Q(name__icontains=word) | Q(description__icontains=word) | Q(tags__name__icontains=word)) for word in words]))

That way, I can break the words in the text and do a pretty cool search. The problem is, I would like to sort by a priority that I create, in case I wanted to do in the following order:

  • Exact result
  • Result that begins with the word / phrase
  • Result that ends with the word / phrase
  • Result containing the word / phrase
  • In this way I will first display the result that is exactly what the user is looking for, then results that begin with what he searches for, finishes and contains.

    But with my code I can not see a way to do this other than by doing the pure sql using case when .

        
    asked by anonymous 14.08.2017 / 17:57

    1 answer

    -1

    I found a solution but I do not know if it is the best. To tell you the truth, it should not be because I have to 2 queries to bring up a list .

    I create 2 querysets, the first for the exact match and the second for the possible matches (as I'm doing in the example I put in the question). Here is the code:

    from functools import reduce    
    
    words = text.split()
    q1 = Question.objects.filter(name__istartswith=text)[:1]
    if q1.count() > 0:
        q1 = [q1[0]]
    else:
        q1 = []
    
    q2 = Question.objects.filter(reduce(lambda x, y: x | y, [Q(name__icontains=word) for word in words]))[:4]
    if q1:
        q2.exclude(id=q1[0].id)
    
    if q2.count() > 0:
        q2 = [q for q in q2]
    else:
        q2 = []
    
    questions = list(q1) + list(q2)
    

    At the end it returns me the 5 results being the 1 perfect match.

        
    14.08.2017 / 23:59