2016-07-19 17 views
2

Ich habe nach einer Antwort gesucht, aber habe nichts gefunden, was dem entspricht, wonach ich gesucht habe.Returning Postgres Verschachteltes JSON-Array

Ich habe zwei Tabellen:

CREATE TABLE skill_tree (
    ID SERIAL PRIMARY KEY, 
    NAME TEXT NOT NULL, 
    DESCRIPTION TEXT NOT NULL 
); 

und

CREATE TABLE skill (
    ID SERIAL PRIMARY KEY, 
    NAME TEXT NOT NULL, 
    DESCRIPTION TEXT NOT NULL, 
    DURATION INTEGER NOT NULL, 
    COOLDOWN INTEGER NOT NULL, 
    SKILL_TREE_ID SERIAL REFERENCES skill_tree(id) 
); 

Ich versuche, JSON von meiner Postgres db so zurückzukehren, dass es wie so strukturiert ist:

[{ 
    "id": 1, 
    "name": "skill tree 1", 
    "description": "skill tree description", 
    "skills": [{ 
     "id": 1, 
     "name": "skill 1", 
     "description": "skill 1 desc", 
     "duration": 10, 
     "cooldown": 20 
    }, { 
     "id": 2, 
     "name": "skill 2", 
     "description": "skill 2 desc", 
     "duration": 20, 
     "cooldown": 30 
    }] 
}] 

Ich konnte etwas ähnliches von hier bekommen [PostgreSQL and nodejs/pg, return nested JSON aber war nicht in der Lage, etwas mehr tha zurückzuholen n Name der Fähigkeit.

+1

Jetzt sehe ich was falsch ist. Die Spalte "SKILL_TREE_ID" darf keine Seriennummer sein. –

Antwort

5

Die Tabelle skill sollte wie folgt aussehen:

CREATE TABLE skill (
    ID SERIAL PRIMARY KEY, 
    NAME TEXT NOT NULL, 
    DESCRIPTION TEXT NOT NULL, 
    DURATION INTEGER NOT NULL, 
    COOLDOWN INTEGER NOT NULL, 
    SKILL_TREE_ID INTEGER REFERENCES skill_tree(id) -- cannot be serial! 
); 

Verwenden jsonb_build_object() und jsonb_agg(). Beachten Sie, dass die Abfrage dem erwarteten Objekt ähnelt.

select jsonb_pretty(jsonb_agg(js_object)) result 
from (
    select 
     jsonb_build_object(
      'id', id, 
      'name', name, 
      'description', description, 
      'skills', jsonb_agg(skill) 
     ) js_object 
    from (
     select 
      t.*, 
      jsonb_build_object(
       'id', s.id, 
       'name', s.name, 
       'description', s.description, 
       'duration', duration, 
       'cooldown', cooldown 
      ) skill 
     from skill_tree t 
     join skill s on s.skill_tree_id = t.id 
     ) s 
    group by id, name, description 
    ) s; 

Ich habe das Ergebnis mit jsonb_pretty() gewickelt, um eine schöne Ausgabe zu erhalten:

     result      
------------------------------------------------- 
[            + 
    {           + 
     "id": 1,        + 
     "name": "skill tree 1",    + 
     "skills": [       + 
      {         + 
       "id": 1,      + 
       "name": "skill 1",    + 
       "cooldown": 20,    + 
       "duration": 10,    + 
       "description": "skill 1 desc" + 
      },         + 
      {         + 
       "id": 2,      + 
       "name": "skill 2",    + 
       "cooldown": 30,    + 
       "duration": 30,    + 
       "description": "skill 2 desc" + 
      }         + 
     ],          + 
     "description": "skill tree description"+ 
    }           + 
] 

Beachten Sie, dass die Reihenfolge der Elemente eines JSON-Objekt nicht definiert ist.

+0

sieht aus wie das ist die Lösung! werde das heute Abend versuchen – invictvs1