如何在 Django 模型字段中使用 SearchRank?

Posted

技术标签:

【中文标题】如何在 Django 模型字段中使用 SearchRank?【英文标题】:How can I use SearchRank in a Django model field? 【发布时间】:2021-11-14 13:44:31 【问题描述】:

我有一个模特帖子:

class Post(models.Model):
    post_title = models.CharField(max_length=120)
    post_subtitle = models.TextField()
    post_text = models.TextField()
    vector_column = SearchVectorField(null=True)
    
    class Meta:
        indexes = (GinIndex(fields=['vector_column']),)

我在数据库中创建了一个触发器来更新vector_column 值:

create function core_post_trigger() returns trigger as $$
begin
    new.vector_column :=
        setweight(to_tsvector('pg_catalog.english', coalesce(new.post_title, '')), 'A') ||
        setweight(to_tsvector('pg_catalog.english', coalesce(new.post_subtitle, '')), 'B') ||
        setweight(to_tsvector('pg_catalog.english', coalesce(new.post_text, '')), 'C');
    return new; 
end
$$ language plpgsql;

create trigger vector_column_trigger
before insert or update on core_post
for each row execute procedure
core_post_trigger();

我像这样搜索这个模型:

Post.objects.filter(vector_column=SearchQuery(query, config='english', search_type='websearch')

虽然我在此搜索中应用了权重,但我没有应用排名 (to_tsrank)。我知道我可以像这样在 Django 中申请排名:

vector = SearchVector('post_title', weight='A', config='english') + SearchVector('post_subtitle', weight='B', config='english') + 
SearchVector('post_text', weight='C', config='english')

query = SearchQuery(query, search_type='websearch')

Post.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank')

问题是我不知道如何将SearchRank 与我的vector_column 列一起使用,因为该列有一个GinIndex。如果我使用上面创建的这个vector变量,我就不会使用索引,那么这个搜索就会很慢。我尝试以各种方式编写此查询,但我不知道该怎么做。例如,我试过这样:

Post.objects.annotate(SearchRank(vector_column, SearchQuery('Angel', config='english'))).order_by('-rank')

但它会引发错误vector_column is not defined

我怎样才能实现它?

【问题讨论】:

【参考方案1】:

我找到了。我需要使用 F 表达式

Post.objects.annotate(
   rank=SearchRank(F('vector_column'),
   SearchQuery(query, config='english'))
).order_by('-rank'), 15

【讨论】:

以上是关于如何在 Django 模型字段中使用 SearchRank?的主要内容,如果未能解决你的问题,请参考以下文章

django如何在 search_fields和list_filter 中包含外键字段

如何在 Django 管理员中为模型字段使用自定义表单字段?

如何在Django中基于枚举为模型字段设置默认值?

如何在 Django 模型字段中使用 SearchRank?

如何在 django 中使用模型清理方法并遍历字段

如何使用 django 表单/模型来表示字段之间的选择?