Упорядочение наборов запросов 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

Производительность будет ниже, чем при правильном поле, но это не плохо.

Другие вопросы по тегам