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 по управлению поиском - лучшие места для получения дополнительной информации.