使用pg-promise嵌套查询对象映射

时间:2016-10-26 22:45:28

标签: node.js pg-promise

我正在通过pg-promise查看方法map的示例:

// Build a list of active users, each with the list of user events:
db.task(t => {
    return t.map('SELECT id FROM Users WHERE status = $1', ['active'], user => {
        return t.any('SELECT * FROM Events WHERE userId = $1', user.id)
            .then(events=> {
                user.events = events;
                return user;
            });
    }).then(t.batch);
})
    .then(data => {
        // success
    })
    .catch(error => {
        // error
    });

让我们说Event实体与...有一对多的关系。 Cars,我想列出连接到每个cars的所有event,当我想要的对象深度超过一级时,如何使用map函数?

我想要的结果可能是这样的:

[{
    //This is a user
    id: 2,
    first_name: "John",
    last_name: "Doe",
    events: [{
        id: 4,
        type: 'type',
        cars: [{
            id: 4,
            brand: 'bmw'
        }]
    }]
}]

1 个答案:

答案 0 :(得分:5)

我是pg-promise的作者。

function getUsers(t) {
    return t.map('SELECT * FROM Users WHERE status = $1', ['active'], user => {
        return t.map('SELECT * FROM Events WHERE userId = $1', user.id, event=> {
            return t.any('SELECT * FROM Cars WHERE eventId = $1', event.id)
                .then(cars=> {
                    event.cars = cars;
                    return event;
                });
        })
            .then(t.batch) // settles array of requests for Cars (for each event)
            .then(events=> {
                user.events = events;
                return user;
            });
    }).then(t.batch); // settles array of requests for Events (for each user)
}

然后使用它:

db.task(getUsers)
    .then(users => {
        // users = an object tree of users->events->cars
    })
    .catch(error => {
        // error
    });

方法map简化了将检索到的行映射到其他内容的过程,因为我们将它们映射到promises中,需要解决这些问题,我们使用方法batch。我们为cars的每个内部请求执行此操作,然后在顶层执行此操作,以解决events的请求数组。

还可以在此处找到更快速的单一查询方法: