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

Posted

技术标签:

【中文标题】如何在 Django 中基于全文搜索功能 SearchRank 创建自定义排名?【英文标题】:How to create a custom rank based on Full Text Search Function SearchRank in Django? 【发布时间】:2018-02-18 04:52:09 【问题描述】:

我想自定义 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】:

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

【讨论】:

以上是关于如何在 Django 中基于全文搜索功能 SearchRank 创建自定义排名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 数组字段中执行全文搜索

Django 如何实现全文检索?

Django:如何在 Postgresql 中对日语(多字节字符串)进行全文搜索

Django之使用haystack+whoosh实现搜索功能

搜索引擎之全文搜索算法功能实现(基于Lucene)

搜索引擎之全文搜索算法功能实现(基于Lucene)