是否可以使用 Django 的 SearchVectorField 保留连接字段以进行全文搜索?
例如:
class P(models.Model):
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
search_vector = SearchVectorField(null=True, blank=True)
代码:
p = P.objects.get(id=1)
p.search_vector = SearchVector('brand__name')
p.save()
引发此异常:
FieldError: Joined field references are not permitted in this query
如果这是不可能的,如何提高连接注释查询的性能?
我找到了解决您问题的方法:
p = P.objects.annotate(brand_name=SearchVector('brand__name')).get(id=1)
p.search_vector = p.brand_name
p.save()
更新2023-11-23
如官方文档中所述:
如果您只是更新记录,不需要对模型对象执行任何操作,最有效的方法是调用 update(),而不是将模型对象加载到内存中。
使用 update() 还可以防止竞争条件,即在加载对象和调用 save() 之间的短时间内数据库中的某些内容可能会发生变化。
最后,意识到 update() 在 SQL 级别进行更新,因此不会在模型上调用任何 save() 方法,也不会发出 pre_save 或 post_save 信号(这是调用 Model.save 的结果) ()).
因此,在这种情况下,您可以使用此查询对数据库执行单个 SQL 查询:
from django.contrib.postgres.search import SearchVector
from django.db.models import F
P.objects.annotate(
brand_name=SearchVector('brand__name')
).filter(
id=1
).update(
search_vector=F('brand_name')
)
或者更短的形式(由@christophe31建议)是:
from django.contrib.postgres.search import SearchVector
P.objects.filter(id=1).update(search_vector=SearchVector('brand__name))
以上两种解决方案都会在数据库中生成相同的 SQL 代码。