Fixed #31088 -- Added support for websearch searching in SearchQuery.
This commit is contained in:
parent
972d93a95e
commit
ff00a05347
1
AUTHORS
1
AUTHORS
|
@ -390,6 +390,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
James Murty
|
||||
James Tauber <jtauber@jtauber.com>
|
||||
James Timmins <jameshtimmins@gmail.com>
|
||||
James Turk <dev@jamesturk.net>
|
||||
James Wheare <django@sparemint.com>
|
||||
Jannis Leidel <jannis@leidel.info>
|
||||
Janos Guljas
|
||||
|
|
|
@ -134,6 +134,7 @@ class SearchQuery(SearchQueryCombinable, Value):
|
|||
'plain': 'plainto_tsquery',
|
||||
'phrase': 'phraseto_tsquery',
|
||||
'raw': 'to_tsquery',
|
||||
'websearch': 'websearch_to_tsquery',
|
||||
}
|
||||
|
||||
def __init__(self, value, output_field=None, *, config=None, invert=False, search_type='plain'):
|
||||
|
|
|
@ -64,6 +64,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
def is_postgresql_10(self):
|
||||
return self.connection.pg_version >= 100000
|
||||
|
||||
@cached_property
|
||||
def is_postgresql_11(self):
|
||||
return self.connection.pg_version >= 110000
|
||||
|
||||
@cached_property
|
||||
def is_postgresql_12(self):
|
||||
return self.connection.pg_version >= 120000
|
||||
|
@ -71,4 +75,5 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
has_bloom_index = property(operator.attrgetter('is_postgresql_9_6'))
|
||||
has_brin_autosummarize = property(operator.attrgetter('is_postgresql_10'))
|
||||
has_phraseto_tsquery = property(operator.attrgetter('is_postgresql_9_6'))
|
||||
has_websearch_to_tsquery = property(operator.attrgetter('is_postgresql_11'))
|
||||
supports_table_partitions = property(operator.attrgetter('is_postgresql_10'))
|
||||
|
|
|
@ -80,8 +80,11 @@ looks for matches for all of the resulting terms.
|
|||
If ``search_type`` is ``'plain'``, which is the default, the terms are treated
|
||||
as separate keywords. If ``search_type`` is ``'phrase'``, the terms are treated
|
||||
as a single phrase. If ``search_type`` is ``'raw'``, then you can provide a
|
||||
formatted search query with terms and operators. Read PostgreSQL's `Full Text
|
||||
Search docs`_ to learn about differences and syntax. Examples:
|
||||
formatted search query with terms and operators. If ``search_type`` is
|
||||
``'websearch'``, then you can provide a formatted search query, similar to the
|
||||
one used by web search engines. ``'websearch'`` requires PostgreSQL ≥ 11. Read
|
||||
PostgreSQL's `Full Text Search docs`_ to learn about differences and syntax.
|
||||
Examples:
|
||||
|
||||
.. _Full Text Search docs: https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
|
||||
|
||||
|
@ -91,6 +94,7 @@ Search docs`_ to learn about differences and syntax. Examples:
|
|||
>>> SearchQuery('red tomato', search_type='phrase') # a phrase
|
||||
>>> SearchQuery('tomato red', search_type='phrase') # a different phrase
|
||||
>>> SearchQuery("'tomato' & ('red' | 'green')", search_type='raw') # boolean operators
|
||||
>>> SearchQuery("'tomato' ('red' OR 'green')", search_type='websearch') # websearch operators
|
||||
|
||||
``SearchQuery`` terms can be combined logically to provide more flexibility::
|
||||
|
||||
|
@ -102,6 +106,10 @@ Search docs`_ to learn about differences and syntax. Examples:
|
|||
See :ref:`postgresql-fts-search-configuration` for an explanation of the
|
||||
``config`` parameter.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Support for ``'websearch'`` search type was added.
|
||||
|
||||
``SearchRank``
|
||||
==============
|
||||
|
||||
|
|
|
@ -97,6 +97,9 @@ Minor features
|
|||
:class:`~django.db.models.SmallIntegerField`, and
|
||||
:class:`~django.db.models.DecimalField`.
|
||||
|
||||
* :class:`~django.contrib.postgres.search.SearchQuery` now supports
|
||||
``'websearch'`` search type on PostgreSQL 11+.
|
||||
|
||||
:mod:`django.contrib.redirects`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -202,6 +202,45 @@ class MultipleFieldsTest(GrailTestData, PostgreSQLTestCase):
|
|||
)
|
||||
self.assertSequenceEqual(searched, [self.french])
|
||||
|
||||
@skipUnlessDBFeature('has_websearch_to_tsquery')
|
||||
def test_web_search(self):
|
||||
line_qs = Line.objects.annotate(search=SearchVector('dialogue'))
|
||||
searched = line_qs.filter(
|
||||
search=SearchQuery(
|
||||
'"burned body" "split kneecaps"',
|
||||
search_type='websearch',
|
||||
),
|
||||
)
|
||||
self.assertSequenceEqual(searched, [])
|
||||
searched = line_qs.filter(
|
||||
search=SearchQuery(
|
||||
'"body burned" "kneecaps split" -"nostrils"',
|
||||
search_type='websearch',
|
||||
),
|
||||
)
|
||||
self.assertSequenceEqual(searched, [self.verse1])
|
||||
searched = line_qs.filter(
|
||||
search=SearchQuery(
|
||||
'"Sir Robin" ("kneecaps" OR "Camelot")',
|
||||
search_type='websearch',
|
||||
),
|
||||
)
|
||||
self.assertSequenceEqual(searched, [self.verse0, self.verse1])
|
||||
|
||||
@skipUnlessDBFeature('has_websearch_to_tsquery')
|
||||
def test_web_search_with_config(self):
|
||||
line_qs = Line.objects.annotate(
|
||||
search=SearchVector('scene__setting', 'dialogue', config='french'),
|
||||
)
|
||||
searched = line_qs.filter(
|
||||
search=SearchQuery('cadeau -beau', search_type='websearch', config='french'),
|
||||
)
|
||||
self.assertSequenceEqual(searched, [])
|
||||
searched = line_qs.filter(
|
||||
search=SearchQuery('beau cadeau', search_type='websearch', config='french'),
|
||||
)
|
||||
self.assertSequenceEqual(searched, [self.french])
|
||||
|
||||
def test_bad_search_type(self):
|
||||
with self.assertRaisesMessage(ValueError, "Unknown search_type argument 'foo'."):
|
||||
SearchQuery('kneecaps', search_type='foo')
|
||||
|
|
Loading…
Reference in New Issue