如何在Django中基于全文搜索功能SearchRank创建自定义排名?

时间:2017-09-09 11:57:29

标签: django python-2.7 postgresql full-text-search

我想根据“课程模型”中某个字段的值为某些课程提供更多权重,从而自定义SearchRank提供的排名结果。

我想使用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')

并创建一个新的:

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

并使用这个新排名来订购课程:

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

但这给了我错误:

  

AttributeError:' list'对象没有属性' resolve_expression

我还尝试在重新排序之前修改原始排名,但它似乎使用初始排名值与新排名:

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')

这样做的最佳方式是什么?

在Postgresql文档中,我可以阅读:

  

您可以编写自己的排名功能和/或将其结果与其他因素结合起来,以满足您的特定需求。

但我不知道如何做到这一点。

我正在使用Django 1.11.1和python 2.7.13

1 个答案:

答案 0 :(得分:0)

您可以使用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')