Упорядочение наборов запросов Django с использованием свойств JSONField
У меня есть модель, которая выглядит примерно так:
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, но я не могу найти что-то уместное.
Ссылка на тикет о его реализации в будущем
У меня тоже есть другой вопрос. Допустим, мы фильтруем и заказываем, используя JSONField. Придется ли ORM получать все объекты, фильтровать и упорядочивать их перед отправкой первых 20 в таком случае? То есть производительность будет на законных основаниях ниже?
Очевидно, я знаю, что нормализованная база данных намного лучше для этих вещей, но мои руки вроде как связаны.
1 ответ
Вы можете использовать синтаксис 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
Производительность будет ниже, чем при правильном поле, но это не плохо.