尝试使用SearchVector
在Django
中使用Postgres
搜索,如果包含给定字符串,我想排除结果。这可能吗?
示例来自docs:
Entry.objects.annotate(search=SearchVector('body_text', 'blog__tagline')).filter(search='Cheese')
如果我想排除blog__tagline
包含"queso"的对象,该怎么办?
不能排除带有"queso"的对象在注释之前,因为我想在不执行搜索时包含它们。
Entry.objects.exclude(blog__tagline__icontains='queso').annotate(search=SearchVector('body_text', 'blog__tagline')).filter(search='Cheese')
如果你需要快速修复,我推荐exclude
。
我可以提出两个解决方案:首先,可以在SearchQuery
对象上应用逻辑运算符。
cheese = SearchQuery('cheese')
not_cheese = ~SearchQuery('cheese')
cheese_and_not_queso = SearchQuery('cheese') & ~SearchQuery('queso')
...
Entry.objects.annotate(search=SearchVector('body_text', 'blog__tagline')).filter(search=cheese_and_not_queso)
第二,您可以在查询中使用搜索操作符,但是您需要一些额外的配置。filter(search='Cheese')
它创建了一个SearchQuery,相当于filter(search=SearchQuery('Cheese', search_type='plain'))
。在普通搜索类型中(参见Postgres文档),搜索操作符和特殊的全文搜索字符被剥离,我们不希望这样。search_type
接受四种模式:'plain', 'phrase', 'raw'和'websearch'。如果您使用'raw'作为search_type,则可以在查询字符串中使用这些操作符:
& (AND)
| (OR)
! (NOT)
<-> (FOLLOWED BY)
因此您可以将查询更改为SearchQuery("cheese & !queso", search_type='raw')
。其他搜索类型呢?"短语"就像剥离行为的"普通",但"websearch"使我们能够在查询中使用网络搜索引擎语法(如Google)。因此,查询可以在SearchQuery("cheese -queso", search_type='websearch')
中改写。关于全文搜索的Django文档和关于控制搜索的Postgres和Postgres文档是了解更多信息的最好地方。