首页 > 解决方案 > 对模型中的多个字段执行全文搜索(Django 2.1)

问题描述

我想对模型中的两个字段执行全文搜索。这是我当前的代码:

if 'keyword' in request.GET:
    search_term = request.GET['keyword']
    vector = SearchVector('Title', weight='A') + SearchVector('Content', weight='B')
    articles = articles.annotate(similarity=TrigramSimilarity(vector, search_term),).filter(similarity__gt=0.01).order_by('-similarity')

此代码返回错误消息

function similarity(tsvector, unknown) does not exist

我认为这是因为我没有正确组合字段,因为当我只将一个字段代替 时vector,它可以正常工作。如果 pg_trgm 扩展没有正确安装,trigram 搜索就不能在一个字段上工作,对吧?在多个领域进行搜索的正确方法是什么?

标签: django

解决方案


我误读了您的问题,错误显示您已similarity安装功能,但表示您不能将搜索向量与该similarity功能一起使用。由于要搜索相似度高于阈值的模式,因此可以分别计算每个字段的相似度并返回最大值。您不能将它们与等级结合起来。尝试这个:

from django.db.models.functions import Greatest

articles.annotate(
    similarity=Greatest(
         TrigramSimilarity('Title', search_term), 
         TrigramSimilarity('Content', search_term)
    )).filter(similarity__gte=0.1).order_by('-similarity')

如果你想给“标题”更高的权重,你可以用一个数学函数来增加权重,而不是使用Greatest

A = 1.0; B = 0.4
articles.annotate(
    similarity=(A/(A+B) * TrigramSimilarity('Title', search_term) 
               + B/(A+B) * TrigramSimilarity('Content', search_term))
    ).filter(similarity__gte=0.1).order_by('-similarity')

请注意,如果 'Title' 中有很好的匹配,而 'Content' 中没有与 相关的匹配,后者将降低相似度值Greatest,因此您可能希望将阈值设置得更低。

注意2:相似度查看完整的字符串,因此如果您有很长的文本('Content')并且只有一个关键字要搜索,即使关键字包含在'Content'中,相似度也会返回0。对于全文搜索,最好SearchRankSearchVector.


推荐阅读