Support plainto_tsquery. Replaces #1894.

Thanks to @kkinder for suggestion and initial patch.
This commit is contained in:
Charles Leifer
2019-03-25 16:19:54 -05:00
parent 59a89ac873
commit fa8fc729f3
3 changed files with 36 additions and 3 deletions
+26 -1
View File
@@ -1030,6 +1030,9 @@ dedicated column for storing ``tsvector`` data:
content = TextField()
search_content = TSVectorField()
.. note::
:py:class:`TSVectorField`, will automatically be created with a GIN index.
You will need to explicitly convert the incoming text data to ``tsvector`` when
inserting or updating the ``search_content`` field:
@@ -1040,7 +1043,14 @@ inserting or updating the ``search_content`` field:
content=content,
search_content=fn.to_tsvector(content))
.. note:: If you are using the :py:class:`TSVectorField`, it will automatically be created with a GIN index.
To perform a full-text search, use :py:class:`TSVectorField.match`:
.. code-block:: python
terms = 'python & (sqlite | postgres)'
results = Blog.select().where(Blog.search_content.match(terms))
For more information, see the `Postgres full-text search docs <https://www.postgresql.org/docs/current/textsearch.html>`_.
postgres_ext API notes
@@ -1556,6 +1566,21 @@ postgres_ext API notes
content=content,
search_content=fn.to_tsvector(content)) # Note `to_tsvector()`.
.. py:method:: match(query[, language=None[, plain=False]])
:param str query: the full-text search query.
:param str language: language name (optional).
:param bool plain: parse search query using plain (simple) parser.
:returns: an expression representing full-text search/match.
Example:
.. code-block:: python
# Perform a search using the "match" method.
terms = 'python & (sqlite | postgres)'
results = Blog.select().where(Blog.search_content.match(terms))
.. _mysql_ext:
+3 -2
View File
@@ -343,9 +343,10 @@ class TSVectorField(IndexedFieldMixin, TextField):
field_type = 'TSVECTOR'
__hash__ = Field.__hash__
def match(self, query, language=None):
def match(self, query, language=None, plain=False):
params = (language, query) if language is not None else (query,)
return Expression(self, TS_MATCH, fn.to_tsquery(*params))
func = fn.plainto_tsquery if plain else fn.to_tsquery
return Expression(self, TS_MATCH, func(*params))
def Match(field, query, language=None):
+7
View File
@@ -461,6 +461,13 @@ class TestTSVectorField(ModelTestCase):
self.assertMessages(M('god | things'), [1, 2, 4])
self.assertMessages(M('god & things'), [])
# Using the plain parser we cannot express "OR", but individual term
# match works like we expect and multi-term is AND-ed together.
self.assertMessages(M('god | things', plain=True), [])
self.assertMessages(M('god', plain=True), [1])
self.assertMessages(M('thing', plain=True), [2, 4])
self.assertMessages(M('faith things', plain=True), [2, 4])
class BaseJsonFieldTestCase(object):
M = None # Subclasses must define this.