Postgres: поиск по аннотированным / объединенным значениям json - PullRequest
0 голосов
/ 17 мая 2019

У меня есть модель django, в которой используется столбец postgres json.

class ClassName:
    json=JsonField()

Это схема в поле json.

{
  'lev1': {
    'lev2': {
      first_name: 'Alex',
      last_name: 'Anderson',
      street: '242 Bell St,',
      city:'New York',
      state:'NY',
    }
}

Теперь у меня есть эти данные, я должен отфильтровать их по полному имени пользователя и полному адресу.

Я ищу что-то вроде

ClassName.objects.annotate(
    full_name=Concat(F('lvl1__lvl2__first_name'), Value(' '),
                    F('lvl1__lvl2__last_name')),
    full_address=Concat(F('lvl1__lvl2__address'), Value(' '),
                        F('lvl1__lvl2__city'), Value(' '),
                        F('lvl1__lvl2__state'), Value(' '),
                        F('lvl1__lvl2__zipcode')),
).filter(full_name__icontains="Alex Anderson")

Я перепробовал все различные функции json, не смог получить правильную комбинацию.

1 Ответ

1 голос
/ 17 мая 2019

К сожалению, существует проблема в Django, которая не позволяет использовать поля JSON непосредственно в функции F ... Это препятствует работе вашего кода ...

Решение для этоговстроить необработанный фрагмент SQL в ваш код.Ужасно, но это все, что у нас есть.

TestJsonAnn.objects.annotate(
    full_name=Concat(
        RawSQL("(json->'lev1'->'lev2'->>'first_name')", ()),
        Value(' '),
        RawSQL("(json->'lev1'->'lev2'->>'last_name')", ())
    )
).filter(full_name__icontains="Alex Anderson")

Заметьте, что оператор ->> использовался при последнем извлечении вместо ->.Это необходимо, поскольку -> будет возвращать данные в виде объекта JSON, поэтому ваша строка будет дополнительно заключена в кавычки, ->> возвращает ее в виде строки.Подробнее о извлечении полей в необработанном SQL см. Документация PostgreSQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...