Упорядочение наборов запросов Django с использованием свойств JSONField - PullRequest
0 голосов
/ 08 октября 2018

У меня есть модель, которая выглядит примерно так:

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 Ответ

0 голосов
/ 09 октября 2018

Вы можете использовать синтаксис 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

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

...