Как инкрементально добавить лексему/s к существующему значению документа Django SearchVectorField через ORM?
Вы можете добавить к существующему значению Postgresql tsvector
с помощью ||
, например:
UPDATE acme_table
SET _search =
_search || to_tsvector('english', 'some new words to add to existing ones')
WHERE id = 1234;
Есть ли способ получить доступ к этой функциональности через Django ORM? Т.е. инкрементально добавить к существующему значению SearchVectorField
, а не перестраивать с нуля?
Проблема в том, что свойство SearchVectorField
возвращает tsvector
в виде строки. Поэтому, когда я использую оператор ||
как +
, например:
from django.contrib.postgres.search import SearchVector
instance.my_tsvector_prop += SearchVector(["new", "words"], weight="A", config='english')
Я получаю ошибку:
TypeError: SearchVector can only be combined with other SearchVector instances, got str.
Причина:
type(instance.my_tsvector_prop) == str
Исправление этой открытой ошибки в Django, когда свойство SearchVectorField
возвращает экземпляр SearchVector
, вероятно, позволило бы это сделать, если это возможно. (Хотя это менее эффективно, чем объединение в базе данных. Это обновление будет выполняться асинхронно, поэтому производительность не слишком важна.)
MyModel.objects
.filter(pk=1234)
.update(my_tsvector_prop=
F("my_tsvector_prop") +
SearchVector(
["new_field_name"],
weight="A",
config='english')
)
Возвращается:
FieldError: Cannot resolve expression type, unknown output_field
Другим решением может быть выполнение необработанного SQL UPDATE
, хотя я бы предпочел сделать это через Django ORM, если это возможно, поскольку наши поля tsvector
часто ссылаются на значения во многих джойнах, поэтому было бы неплохо найти устойчивое решение.