Chciałbym, aby PostgreSQL zwracał wynik zapytania jako jedną tablicę JSON. Dany
create table t (a int primary key, b text);
insert into t values (1, 'value1');
insert into t values (2, 'value2');
insert into t values (3, 'value3');
Chciałbym coś podobnego do
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
lub
{"a":[1,2,3], "b":["value1","value2","value3"]}
(właściwie lepiej byłoby znać oba). Próbowałem takich rzeczy
select row_to_json(row) from (select * from t) row;
select array_agg(row) from (select * from t) row;
select array_to_string(array_agg(row), '') from (select * from t) row;
I czuję, że jestem blisko, ale tak naprawdę nie ma. Czy powinienem zajrzeć do innej dokumentacji oprócz 9.15. Funkcje i operatory JSON ?
Nawiasem mówiąc, nie jestem pewien swojego pomysłu. Czy to zwykła decyzja projektowa? Myślę, że mógłbym oczywiście wziąć wynik (na przykład) pierwszego z 3 powyższych zapytań i lekko nim manipulować w aplikacji przed przekazaniem go klientowi, ale jeśli PostgreSQL może bezpośrednio utworzyć końcowy obiekt JSON, byłoby prostsze, ponieważ nadal nie uwzględniłem żadnej zależności od żadnej biblioteki JSON w mojej aplikacji.
json
postgresql
inżynier X
źródło
źródło
Odpowiedzi:
TL; DR
dla tablicy obiektów JSON i
dla obiektu JSON tablic.
Lista obiektów
W tej sekcji opisano sposób generowania tablicy obiektów JSON, przy czym każdy wiersz jest konwertowany na pojedynczy obiekt. Wynik wygląda następująco:
9.3 i nowsze
json_agg
Funkcja produkuje ten wynik po wyjęciu z pudełka. Automatycznie wymyśla, jak przekonwertować swoje dane wejściowe na JSON i agreguje je w tablicę.Nie ma
jsonb
(wprowadzonej w 9.4) wersjijson_agg
. Możesz zagregować wiersze w tablicę, a następnie przekonwertować je:lub połącz
json_agg
z obsadą:Moje testy sugerują, że najpierw agregowanie ich w tablicę jest trochę szybsze. Podejrzewam, że dzieje się tak, ponieważ rzutowanie musi przeanalizować cały wynik JSON.
9.2
9.2 nie ma funkcji
json_agg
lubto_json
, więc musisz użyć starszegoarray_to_json
:Opcjonalnie możesz dołączyć
row_to_json
wywołanie do zapytania:To konwertuje każdy wiersz na obiekt JSON, agreguje obiekty JSON jako tablicę, a następnie konwertuje tablicę na tablicę JSON.
Nie byłem w stanie dostrzec żadnej znaczącej różnicy w wydajności między nimi.
Przedmiot list
W tej sekcji opisano sposób generowania obiektu JSON, w którym każdy klucz jest kolumną w tabeli, a każda wartość jest tablicą wartości kolumny. Oto wynik, który wygląda następująco:
9.5 i nowsze
Możemy wykorzystać
json_build_object
funkcję:Możesz także zagregować kolumny, tworząc pojedynczy wiersz, a następnie przekonwertować go na obiekt:
Zwróć uwagę, że aliasowanie tablic jest absolutnie wymagane, aby zapewnić, że obiekt ma żądane nazwy.
Który z nich jest jaśniejszy, to kwestia opinii. Jeśli korzystasz z tej
json_build_object
funkcji, zdecydowanie zalecam umieszczenie jednej pary klucz / wartość w wierszu, aby poprawić czytelność.Możesz również użyć
array_agg
zamiastjson_agg
, ale moje testy wskazują, żejson_agg
jest nieco szybszy.Brak
jsonb
wersjijson_build_object
funkcji. Możesz agregować w jeden wiersz i konwertować:W przeciwieństwie do innych zapytań o tego rodzaju wynik,
array_agg
wydaje się być nieco szybszy podczas używaniato_jsonb
. Podejrzewam, że jest to spowodowane analizowaniem narzutów i sprawdzaniem poprawności wyniku JSONjson_agg
.Lub możesz użyć wyraźnej obsady:
to_jsonb
Wersja pozwala uniknąć obsady i jest szybszy, według moich badań; ponownie podejrzewam, że jest to spowodowane narzutem związanym z analizowaniem i sprawdzaniem wyniku.9.4 i 9.3
json_build_object
Funkcja była nowa do 9,5, więc trzeba kruszywo i skonwertować do obiektu w poprzednich wersjach:lub
w zależności od tego, czy chcesz,
json
czyjsonb
.(9.3 nie ma
jsonb
.)9.2
W 9.2 nawet nie
to_json
istnieje. Musisz użyćrow_to_json
:Dokumentacja
Znajdź dokumentację dotyczącą funkcji JSON w funkcjach JSON .
json_agg
znajduje się na stronie funkcji agregujących .Projekt
Jeśli wydajność jest ważna, upewnij się, że porównujesz swoje zapytania z własnym schematem i danymi, zamiast ufać moim testom.
To, czy jest to dobry projekt, czy nie, zależy tak naprawdę od konkretnej aplikacji. Jeśli chodzi o łatwość konserwacji, nie widzę żadnego szczególnego problemu. Upraszcza kod aplikacji i oznacza, że w tej części aplikacji jest mniej do utrzymania. Jeśli PG może dać dokładnie taki wynik, jakiego potrzebujesz po wyjęciu z pudełka, jedynym powodem, dla którego mogę wymyślić, aby go nie używać, byłyby względy wydajności. Nie odkrywaj na nowo koła i wszystkiego.
Zero
Funkcje agregujące zwykle zwracają,
NULL
gdy działają na zerowych wierszach. Jeśli jest taka możliwość, możesz użyć,COALESCE
aby ich uniknąć. Kilka przykładów:Lub
Kredyt do Hannes Landeholm za wskazanie tego
źródło
to_json
zamiastrow_to_json
iarray_to_json
SELECT json_agg((column1, column2, ...)) FROM t
- zwróć uwagę na dodatkowe nawiasy. To może nie być oczywiste „po wyjęciu z pudełka”.Również jeśli chcesz wybrać pole z tabeli i zagregować je jako tablicę.
Wynik nadejdzie.
źródło