Dit is gemakkelijk te doen met pg-promise:
function buildTree(t) {
const v = q => t.any('SELECT id, value FROM votes WHERE question_id = $1', q.id)
.then(votes => {
q.votes = votes;
return q;
});
return t.map('SELECT * FROM questions', undefined, v).then(a => t.batch(a));
}
db.task(buildTree)
.then(data => {
console.log(data); // your data tree
})
.catch(error => {
console.log(error);
});
Hetzelfde als hierboven, maar met ES7 async
/await
syntaxis:
await db.task(async t => {
const questions = await t.any('SELECT * FROM questions');
for(const q of questions) {
q.votes = await t.any('SELECT id, value FROM votes WHERE question_id = $1', [q.id]);
}
return questions;
});
// method "task" resolves with the correct data tree
API:kaart, elke, taak, batch
Gerelateerde vragen:
- Koop een ouder + kinderen boom met pg-promise
- Voorwaardelijke taak met pg-promise
En als u slechts één enkele query wilt gebruiken, kunt u met de syntaxis van PostgreSQL 9.4 en hoger het volgende doen:
SELECT json_build_object('id', q.id, 'content', q.content, 'votes',
(SELECT json_agg(json_build_object('id', v.id, 'value', v.value))
FROM votes v WHERE q.id = v.question_id))
FROM questions q
En dan zou je pg-promise-voorbeeld zijn:
const query =
`SELECT json_build_object('id', q.id, 'content', q.content, 'votes',
(SELECT json_agg(json_build_object('id', v.id, 'value', v.value))
FROM votes v WHERE q.id = v.question_id)) json
FROM questions q`;
const data = await db.map(query, [], a => a.json);
En u zult dergelijke complexe query's zeker in externe SQL-bestanden willen bewaren. Zie Bestanden opvragen.
Conclusie
De keuze tussen de twee hierboven gepresenteerde benaderingen moet gebaseerd zijn op de prestatie-eisen van uw toepassing:
- De single-query-benadering is sneller, maar is enigszins moeilijk te lezen of uit te breiden, omdat het redelijk uitgebreid is
- De benadering met meerdere query's is gemakkelijker te begrijpen en uit te breiden, maar is niet geweldig voor de prestaties vanwege het dynamische aantal uitgevoerde query's.
UPDATE-1
Het volgende gerelateerde antwoord biedt meer opties door onderliggende zoekopdrachten samen te voegen, wat een veel betere prestatie zal opleveren:Combineer geneste lus-query's met bovenliggend resultaat pg-promise.
UPDATE-2
Nog een voorbeeld toegevoegd, met ES7 async
/await
benadering.