获得pg承诺的父母+子树

问题描述 投票:3回答:1

我使用pg-promise库与bluebird进行相关查询。我有两个表,a和b,看起来像这样:

|   a   |     |   b   |  
|-------|     |-------|
| a_id  |     | b_id  |
| prop1 |     | prop2 |
              |  b_a  |

其中b.b_a是对a.a_id的引用。我想选择匹配给定prop1的所有条目,结果应包含所有匹配的a行以及每个b的相应a行。这应该适用于两个相关查询。两个查询都可能返回多个结果。

如果表a只返回一行,我可以这样做:

function getResult(prop1) {
    return db.task(function (t) {
        return t.one("select * from a where prop1=$1", prop1)
            .then(function (a) {
                return t.batch([a, t.any("select * from b where b_a=$1", a.a_id)]);
            })
            .then(function (data) {
                var a = data[0];
                var bs = data[1];
                bs.forEach(function (b) {
                    b.a = a;
                });
                return bs;
            });
    });
}

而且我也能够获得所有匹配的b条目,用于多个a结果,如下所示:

function getResult(prop1) {
    return db.task(function (t) {
        return t.many("select * from a where prop1=$1", prop1)
            .then(function (as) {
                var queries = [];
                as.forEach(function (a) {
                    queries.push(t.any("select * from b where b_a=$1", a.id));
                });
                return t.batch(queries); // could concat queries with as here, but there wouldn't be a reference which b row belongs to which a row
            })
            .then(function (data) {
                // data[n] contains all matching b rows
            });
    });
}

但是如何将这两者结合在一起?

javascript postgresql pg-promise
1个回答
3
投票

我是pg-promise的作者。


如果你有2个表:Parent - > Child与1对多关系,你想得到一个匹配的Parent行数组,每行扩展属性children设置为表Child对应行的数组...

有几种方法可以实现这一点,因为pg-promise和promises的组合通常非常灵活。这是最短的版本:

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(t.batch) /* this is short for: data => t.batch(data) */
})
    .then(data => {
        /* data = the complete tree */
    });

这就是我们在那里做的事情:

首先,我们查询Parent项目,然后我们将每一行映射到相应的Child项目的查询中,然后将其行设置为Parent并返回它。然后我们使用方法batch来解析从方法Child返回的map查询数组。


该任务将使用如下数组解决:

[
    {
        "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参考:mapbatch

UPDATE

看到更好的答案:JOIN table as array of results with PostgreSQL/NodeJS

© www.soinside.com 2019 - 2024. All rights reserved.