Postgres: конвертировать графы объектов в JSON - PullRequest
0 голосов
/ 29 ноября 2018

Существует ли процедура, которая преобразует графы объектов Postgres во вложенное дерево JSON?

Контекст:

  • У автора много книг.
  • Книга имеет много рецензий.

Приведенный ниже запрос получает все рецензии на все книги всех авторов:

select author.id, book.title, review.text
from author
left join book on author.id = book.author_id
left join review on book.id = review.book_id;

При моем наборе тестовых данных это возвращает:

id  title                       text
1   Oathbringer                 obath
1   Oathbringer                 oath
1   The Way of Kings            a
1   The Way of Kings            bye
1   The Way of Kings            hi
2   The Eye of the World        w
3   The Fellowship of the Ring  x

Табличный формат неудобен, поэтому я конвертирую его в json:

select json_agg(sub2.*) as data from (
  select sub.id, sub.title, json_agg(sub.text) as review from (
    select author.id, book.title, review.text
    from author
    left join book on author.id = book.author_id
    left join review on book.id = review.book_id
  ) as sub group by sub.id, sub.title
) as sub2;

Данные извлекаются как

[  
   {  
      "id":1,
      "title":"Oathbringer",
      "review":[  
         "obath",
         "oath"
      ]
   },
   {  
      "id":1,
      "title":"The Way of Kings",
      "review":[  
         "a",
         "bye",
         "hi"
      ]
   },
   {  
      "id":2,
      "title":"The Eye of the World",
      "review":[  
         "w"
      ]
   },
   {  
      "id":3,
      "title":"The Fellowship of the Ring",
      "review":[  
         "x"
      ]
   }
]

К сожалению, запрос неправильно, потому что книги для автора не объединяются.Пытаясь исправить это, я написал этот запрос:

select sub2.id, json_agg((sub2.title, sub2.review)) as data from (
  select sub.id, sub.title, json_agg(sub.text) as review from (
    select author.id, book.title, review.text
    from author
    left join book on author.id = book.author_id
    left join review on book.id = review.book_id
  ) as sub group by sub.id, sub.title
) as sub2 group by sub2.id;

Но ключи json перепутаны («f1» вместо «title», «f2» вместо «review»).

Вопросы:

  • Как будет написан правильный запрос?
  • Можно ли изменить json_agg(sub2.*), чтобы явно перечислить столбцы для агрегирования?Наиболее очевидный способ, например, json_agg((sub2.title, sub2.review)) создает объекты json с бессмысленными ключами 'f1', 'f2' и т. Д.

  • Есть ли лучший способ преобразования графов объектов в JSON?Правильно раскладывать запросы, группировать и агрегировать поля сложно.Как бы вы написали программу, которая генерирует SQL-запрос, возвращающий JSON с учетом графа объектов?

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