Существует ли процедура, которая преобразует графы объектов 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 с учетом графа объектов?