是否可以在 Django SearchVectorField 中保留一个连接字段?
Posted
技术标签:
【中文标题】是否可以在 Django SearchVectorField 中保留一个连接字段?【英文标题】:Is it possible to persist a joined field in Djangos SearchVectorField? 【发布时间】:2018-02-02 11:09:38 【问题描述】:是否可以使用 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
如果这是不可能的,您如何提高联合注释查询的性能?
【问题讨论】:
【参考方案1】:我找到了解决您的问题的方法:
p = P.objects.annotate(brand_name=SearchVector('brand__name')).get(id=1)
p.search_vector = p.brand_name
p.save()
2018 年 6 月 29 日更新
据官方documentation报道:
如果您只是更新一条记录并且不需要对模型对象做任何事情,最有效的方法是调用 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')
)
【讨论】:
你不是用那个.get(id=1)
做一个冗余的数据库查询吗?我也在寻找一种解决方案,从外来关系构建搜索向量。
@Nad 我已经用仅在 db 上执行一个查询的解决方案更新了我的答案,但请阅读有关保存和更新之间区别的文档
感谢您。我的问题是我已经有一个模型实例,并且我想从 post_save 信号更新 search_vector。我在这里发布了一个问题***.com/questions/51105651/…
在这里找到了你的答案! ***.com/questions/42679743/… 太棒了,谢谢
@nad 我为您的问题找到了有用的答案。如果它有效,请投票。以上是关于是否可以在 Django SearchVectorField 中保留一个连接字段?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django 中基于全文搜索功能 SearchRank 创建自定义排名?
是否可以在 django rest 框架序列化程序中使用重用 django 表单进行验证?