Je voudrais que PostgreSQL renvoie le résultat d'une requête sous la forme d'un tableau JSON. Donné
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');
Je voudrais quelque chose de similaire à
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
ou
{"a":[1,2,3], "b":["value1","value2","value3"]}
(en fait, il serait plus utile de connaître les deux). J'ai essayé des choses comme
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;
Et je sens que je suis proche, mais pas vraiment là. Dois-je regarder d'autres documents à l'exception de 9.15. Fonctions et opérateurs JSON ?
Au fait, je ne suis pas sûr de mon idée. Est-ce une décision de conception habituelle? Je pense que je pourrais, bien sûr, prendre le résultat (par exemple) de la première des 3 requêtes ci-dessus et le manipuler légèrement dans l'application avant de le servir au client, mais si PostgreSQL peut créer directement l'objet JSON final, ce serait plus simple, car je n'ai toujours inclus aucune dépendance sur une bibliothèque JSON dans mon application.
la source
Réponses:
TL; DR
pour un tableau d'objets JSON, et
pour un objet JSON de tableaux.
Liste des objets
Cette section décrit comment générer un tableau d'objets JSON, chaque ligne étant convertie en un seul objet. Le résultat ressemble à ceci:
9.3 et plus
La
json_agg
fonction produit ce résultat hors de la boîte. Il détermine automatiquement comment convertir son entrée en JSON et l'agrège en un tableau.Il n'y a pas de version
jsonb
(introduite dans 9.4) dejson_agg
. Vous pouvez soit agréger les lignes dans un tableau, puis les convertir:ou combiner
json_agg
avec un casting:Mes tests suggèrent que les agréger d'abord dans un tableau est un peu plus rapide. Je soupçonne que c'est parce que le casting doit analyser l'intégralité du résultat JSON.
9.2
9.2 n'a pas les fonctions
json_agg
outo_json
, vous devez donc utiliser l'anciennearray_to_json
:Vous pouvez éventuellement inclure un
row_to_json
appel dans la requête:Cela convertit chaque ligne en objet JSON, agrège les objets JSON en tant que tableau, puis convertit le tableau en tableau JSON.
Je n'ai pas pu discerner de différence de performance significative entre les deux.
Objet des listes
Cette section décrit comment générer un objet JSON, chaque clé étant une colonne de la table et chaque valeur étant un tableau des valeurs de la colonne. C'est le résultat qui ressemble à ceci:
9.5 et plus
Nous pouvons tirer parti de la
json_build_object
fonction:Vous pouvez également agréger les colonnes, créer une seule ligne, puis la convertir en objet:
Notez que l'aliasing des tableaux est absolument nécessaire pour garantir que l'objet a les noms souhaités.
Laquelle est la plus claire est une question d’opinion. Si vous utilisez la
json_build_object
fonction, je recommande fortement de mettre une paire clé / valeur sur une ligne pour améliorer la lisibilité.Vous pouvez également utiliser
array_agg
à la place dejson_agg
, mais mes tests indiquent quejson_agg
c'est légèrement plus rapide.Il n'y a pas de
jsonb
version de lajson_build_object
fonction. Vous pouvez regrouper en une seule ligne et convertir:Contrairement aux autres requêtes pour ce type de résultat,
array_agg
semble être un peu plus rapide lors de l'utilisationto_jsonb
. Je soupçonne que cela est dû à une analyse des frais généraux et à la validation du résultat JSON dejson_agg
.Ou vous pouvez utiliser une distribution explicite:
La
to_jsonb
version vous permet d'éviter le casting et est plus rapide, selon mes tests; encore une fois, je soupçonne que cela est dû à la surcharge de l'analyse et de la validation du résultat.9.4 et 9.3
La
json_build_object
fonction était nouvelle dans la version 9.5, vous devez donc agréger et convertir en objet dans les versions précédentes:ou
selon que vous voulez
json
oujsonb
.(9.3 n'a pas
jsonb
.)9.2
En 9.2,
to_json
n'existe même pas . Vous devez utiliserrow_to_json
:Documentation
Recherchez la documentation des fonctions JSON dans les fonctions JSON .
json_agg
se trouve sur la page des fonctions d'agrégation .Conception
Si les performances sont importantes, assurez-vous de comparer vos requêtes à votre propre schéma et à vos propres données, plutôt que de faire confiance à mes tests.
Que ce soit une bonne conception ou pas dépend vraiment de votre application spécifique. En termes de maintenabilité, je ne vois pas de problème particulier. Cela simplifie le code de votre application et signifie qu'il y a moins à maintenir dans cette partie de l'application. Si PG peut vous donner exactement le résultat dont vous avez besoin, la seule raison à laquelle je pense pour ne pas l'utiliser serait des considérations de performances. Ne réinventez pas la roue et tout.
Nulls
Les fonctions d'agrégation donnent généralement en retour
NULL
lorsqu'elles fonctionnent sur zéro ligne. Si c'est une possibilité, vous voudrez peut-être l'utiliserCOALESCE
pour les éviter. Quelques exemples:Ou
Crédit à Hannes Landeholm pour avoir signalé
la source
to_json
place derow_to_json
etarray_to_json
SELECT json_agg((column1, column2, ...)) FROM t
- notez les crochets supplémentaires. Cela peut ne pas être évident "hors de la boîte".Aussi si vous voulez un champ sélectionné à partir de la table et agrégé alors en tant que tableau.
Le résultat viendra.
la source