使用 JSONField 的属性对 Django 查询集进行排序



我有一个看起来像这样的模型:

class Person(models.Model):
data = JSONField()

data字段有 2 个属性:nameage。现在,假设我想获取一个分页查询集(每个页面包含 20 人(,其中age大于 25,并且查询集将按降序排序。在通常的设置(即规范化数据库(中,我可以像这样编写此查询:

person_list_page_1 = Person.objects.filter(age > 25).order_by('-age')[:20]

现在,在使用存储在 JSONField 中的键进行筛选和排序时,上述内容的等效性是什么?我已经对此进行了研究,似乎它本来是 2.1 的一个功能,但我似乎找不到任何相关的东西。

链接到有关将来实施的票证

我还有一个问题。假设我们使用 JSONField 进行过滤和排序。在这种情况下,ORM 是否必须在发送前 20 个对象之前获取所有对象、过滤和排序它们?也就是说,性能会合法地变慢吗?

显然,我知道规范化的数据库对这些事情要好得多,但我的手有点束缚。

您可以使用 postgresql sql 语法来提取子字段。然后,可以像在查询集筛选器中模型上的任何其他字段一样使用它们。

from django.db.models.expressions import RawSQL
Person.objects.annotate(
age=RawSQL("(data->>'age')::int", [])
).filter(age__gte=25).order_by('-age')[:20]

有关其他运算符和函数,请参阅 postgresql 文档。 在某些情况下,您可能必须添加显式类型转换(例如::int(

https://www.postgresql.org/docs/current/static/functions-json.html

性能会比使用适当的字段慢,但还不错。

最新更新