我想对模型中的两个字段执行全文搜索。这是我当前的代码:
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搜索将无法在一个字段上进行,对吗?在多个字段中进行搜索的正确方法是什么?
答案 0 :(得分:1)
我误解了您的问题,该错误表明您已经安装了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}与Greatest
的匹配度很高,而'Content'的匹配度不高,则后者会降低相似度值,因此您可能希望将阈值设置得较低。
注意2:相似性会查看完整的字符串,因此,如果您有一段较长的文字(“内容”)并且仅搜索一个关键字,即使该关键字包含在“内容”中,相似性也将返回0 。对于全文搜索,最好将SearchRank
与SearchVector
一起使用。
答案 1 :(得分:0)
我相信您需要在数据库中安装pg_trgm
扩展名。 CouchDB mailing list表示必须使用这些功能。
docs:
from django.contrib.postgres.operations import TrigramExtension
operations = [TrigramExtension()]