如果我在一个网站上搜索多个关键字(并且没有引号) - 例如红色汽车 - 我的期望是包含“红色汽车”的项目应该是第一个,然后是包含两个关键字(但非按顺序)的项目,后跟包含其中一个关键字的项目。 (我相信这是Lucene系统中的默认行为,但是自从我使用它们已经有一段时间了,所以不能肯定地说。)
我希望Postgres全文搜索会自动执行此操作,但我的早期测试显示情况并非如此:
## ASSUME: items in database: <blue car>, <green car>, <red truck>
keywords = "red car"
items = ForSaleItem.objects.filter(name__search=keywords)
## RESULT: items is empty/None, whereas it should have each of
## the items since one keyword matches.
我看到的黑客是使用Django的析取运算符,但我希望有一些不那么黑的东西。我也很确定这个黑客不会把精确的匹配放在列表的顶部。这是黑客:
from django.db.models import Q
keyword_query = Q()
for keyword in keywords.split(' '):
keyword_query.add(Q(name__search=keyword), Q.OR)
items = ForSaleItem.objects.filter(keyword_query)
是否有一些我缺少的设置/ API(或者在postgres方面可实现的东西)获得了我期望的功能?
答案 0 :(得分:2)
感谢@Dharshan指出我正确的方向。正如他或她所指出的,SearchQuery
对象的分离将允许匹配任一关键字。此外,要将包含两个关键字的项目放在列表顶部 -
如Django full text search docs中所述 - SearchRank
类可以按如下方式使用:
vector = SearchVector('name')
query = SearchQuery('red') | SearchQuery('car')
items = ForSaleItem.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank')
答案 1 :(得分:0)
items = ForSaleItem.objects.filter(name__contains=keywords)