使用 JSONField 的属性排序 Django 查询集
Ordering Django querysets using a JSONField's properties
我有一个看起来像这样的模型:
class Person(models.Model):
data = JSONField()
data
字段有 2 个属性,name
和 age
。现在,假设我想获得一个分页查询集(每页包含 20 人),其中过滤器 age
大于 25,并且查询集按降序排列。在通常的设置中,即规范化数据库,我可以这样写这个查询:
person_list_page_1 = Person.objects.filter(age > 25).order_by('-age')[:20]
现在,当使用存储在 JSONField 中的键进行过滤和排序时,上面的等价物是什么?我已经对此进行了研究,它似乎是 2.1 的一个特性,但我似乎找不到任何相关的东西。
Link to the ticket about it being implemented in the future
我还有一个问题。假设我们使用 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
性能会比适当的字段慢,但还不错。
我有一个看起来像这样的模型:
class Person(models.Model):
data = JSONField()
data
字段有 2 个属性,name
和 age
。现在,假设我想获得一个分页查询集(每页包含 20 人),其中过滤器 age
大于 25,并且查询集按降序排列。在通常的设置中,即规范化数据库,我可以这样写这个查询:
person_list_page_1 = Person.objects.filter(age > 25).order_by('-age')[:20]
现在,当使用存储在 JSONField 中的键进行过滤和排序时,上面的等价物是什么?我已经对此进行了研究,它似乎是 2.1 的一个特性,但我似乎找不到任何相关的东西。
Link to the ticket about it being implemented in the future
我还有一个问题。假设我们使用 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
性能会比适当的字段慢,但还不错。