2017-09-09 3 views
2

Je souhaite personnaliser les résultats obtenus par SearchRank en donnant plus de poids à certains cours en fonction de la valeur d'un champ dans le modèle de cours.Comment créer un classement personnalisé basé sur la fonction de recherche de texte intégral SearchRank dans Django?

Je veux utiliser le rang donné par SearchRank:

vector=SearchVector('title', weight='A')+SearchVector('full_description', weight='B') 
query = SearchQuery(search) 
courses=Course.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by('-rank') 

et créer une nouvelle:

rank2=[course.rank*2 if course.field1==Value1 else course.rank for course in courses] 

Et utiliser ce nouveau rang pour commander les cours:

courses.annotate(rank2=rank2).order_by('-rank2') 

Mais cela me donne l'erreur:

AttributeError: 'list' object has no attribute 'resolve_expression

J'ai aussi essayé de modifier le rang d'origine avant de réordonnancement à nouveau, mais il semble utiliser les valeurs de classement initial par rapport aux nouvelles:

def adjust_rank(courses): 
courses_temp=courses 
for course in courses_temp: 
    if course.field1==Value1: 
     course.rank=course.rank*2 
return courses_temp 

courses2=adjust_rank(courses).order_by('-rank') 

Quelle est la meilleure façon de le faire?

Dans la documentation Postgresql, je peux lire:

You can write your own ranking functions and/or combine their results with additional factors to fit your specific needs.

Mais je n'ai aucune idée sur la façon de le faire.

J'utilise Django 1.11.1 et python 2.7.13

+0

Avez-vous vu ma réponse? Pouvez-vous dire si cela fonctionne pour vous et voter? Je vous remercie –

Répondre

0

Vous pouvez le faire avec une requête, en utilisant conditional expression:

from django.db.models import Case, When, F 
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector 

vector = SearchVector('title', weight='A') + SearchVector('full_description', weight='B') 
query = SearchQuery(search) 
rank = SearchRank(vector, query) 

Course.objects.annotate(
    rank0=rank, 
    rank1=Case(When(field1='Value1', then='rank0'), default=0.0), 
    rank2=F('rank0') + F('rank1') 
).filter(rank0__gte=0.3).order_by(-'rank2')