Django/Postgres полнотекстовый поиск - исключить, если значение содержит <STRING>

Пытаюсь использовать Postgres поиск в Django с помощью SearchVector и хочу исключить результаты, содержащие заданную строку. Возможно ли это?

Пример из документации:

Entry.objects.annotate(search=SearchVector('body_text', 'blog__tagline')).filter(search='Cheese')

Что если я хочу исключить объекты, blog__tagline содержащие "queso"?

Я не могу исключить объекты с "queso" перед аннотацией, потому что я хочу включить их, когда поиск не выполняется.

Как насчет чего-то вроде:

queryset = Entry.objects.exclude(
    field__icontains = "some string"
)
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 doc) операторы поиска и специальные символы полнотекстового поиска зачеркнуты, а нам это не нужно. search_type принимает четыре режима: 'plain', 'phrase', 'raw' и 'websearch'. Если вы используете 'raw' в качестве типа поиска, вы можете использовать эти операторы в строке запроса:

& (AND) 
| (OR)
! (NOT)
<-> (FOLLOWED BY)

Поэтому вы можете изменить свой запрос на SearchQuery("cheese & !queso", search_type='raw'). А как насчет других типов поиска? 'phrase' подобен 'plain' в поведении зачистки, но 'websearch' позволяет нам использовать синтаксис поисковой системы (например, Google) в нашем запросе. Поэтому запрос может быть перефразирован в SearchQuery("cheese -queso", search_type='websearch')

Django doc по полнотекстовому поиску и Postgres и Postgres doc по управлению поиском - лучшие места для получения дополнительной информации.

Вернуться на верх