Jeg er forfatter til pg-promise.
Når du har 2 tabeller:Parent
-> Child
med 1-til-mange-forhold, og du ønsker at få en række matchende Parent
rækker, hver række udvidet med egenskaben children
indstillet til en matrix af de tilsvarende rækker fra tabel Child
...
Der er flere måder at opnå dette på, da kombinationen af pg-løfte og løfter generelt er meget fleksibel. Her er den korteste version:
db.task(t => {
return t.map('SELECT * FROM Parent WHERE prop1 = $1', [prop1], parent => {
return t.any('SELECT * FROM Child WHERE parentId = $1', parent.id)
.then(children => {
parent.children = children;
return parent;
});
}).then(a => t.batch(a))
})
.then(data => {
/* data = the complete tree */
});
Dette er, hvad vi gør der:
Først forespørger vi efter Parent
elementer, så kortlægger vi hver række til en forespørgsel for det tilsvarende Child
elementer, som derefter sætter sine rækker i Parent
og returnerer den. Derefter bruger vi metodebatch til at løse arrayet af Child
forespørgsler returneret fra metodeoversigt.
OPDATERING til ES7
Her er det samme som ovenfor, men ved at bruge ES7 async
/await
syntaks:
await db.task(async t => {
const parents = await t.any('SELECT * FROM Parent WHERE prop1 = $1', [prop1]);
for(const p of parents) {
p.children = await t.any('SELECT * FROM Child WHERE parentId = $1', [p.id]);
}
return parents;
});
// the task resolves with the correct data tree
Opgaven løses med et array som dette:
[
{
"parent1-prop1", "parent1-prop2",
"children": [
{"child1-prop1", "child1-prop2"},
{"child2-prop1", "child2-prop2"}
]
},
{
"parent2-prop1", "parent2-prop2",
"children": [
{"child3-prop1", "child3-prop2"},
{"child4-prop1", "child4-prop2"}
]
}
]
API-referencer:kort, batch
OPDATERING
Se et bedre svar på dette:JOIN-tabellen som en række resultater med PostgreSQL/NodeJS.