How do you incrementally add lexeme/s to an existing Django SearchVectorField document value through the ORM?
You can add to an existing Postgresql tsvector
value using ||
, for example:
UPDATE acme_table
SET _search =
_search || to_tsvector('english', 'some new words to add to existing ones')
WHERE id = 1234;
Is there any way to access this functionality via the Django ORM? I.e. incrementally add to an existing SearchVectorField
value rather than reconstruct from scratch?
The issue I'm having is the SearchVectorField
property returns the tsvector
as a string. So when I use the ||
operator as +
, eg:
from django.contrib.postgres.search import SearchVector
instance.my_tsvector_prop += SearchVector(["new", "words"], weight="A", config='english')
I get the error:
TypeError: SearchVector can only be combined with other SearchVector instances, got str.
Because:
type(instance.my_tsvector_prop) == str
A fix to this open Django bug whereby a SearchVectorField
property returns a SearchVector
instance would probably enable this, if possible. (Although less efficient than combining in the database. This update will run asynchronously so performance is not too important.)
MyModel.objects
.filter(pk=1234)
.update(my_tsvector_prop=
F("my_tsvector_prop") +
SearchVector(
["new_field_name"],
weight="A",
config='english')
)
Returns:
FieldError: Cannot resolve expression type, unknown output_field
Another solution would be to run a raw SQL UPDATE
, although I'd rather do it through the Django ORM if possible as our tsvector
fields often reference values many joins away, so it'd be nice to find a sustainable solution.