【问题标题】:Nested query object mapping with pg-promise使用 pg-promise 的嵌套查询对象映射
【发布时间】:2017-03-09 11:17:59
【问题描述】:

我正在通过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,我想列出所有连接到每个eventcars,当我想要的对象超过一层深度时,如何使用map 函数?

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

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

【问题讨论】:

    标签: node.js pg-promise


    【解决方案1】:

    我是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 简化了将检索到的行映射到其他内容,并且由于我们将它们映射到promise,因此需要解决这些问题,为此我们使用方法batch。我们对cars 的每个内部请求数组执行此操作,然后在顶层 - 解决events 的请求数组。

    更新

    如果将树形逻辑倒置,可能更易于阅读和维护:

    function getUsers(t) {
        const getCars = eventId => t.any('SELECT * FROM Cars WHERE eventId = $1', eventId);
    
        const getEvents = userId => t.map('SELECT * FROM Events WHERE userId = $1', userId, event => {
            return getCars(event.id)
                .then(cars => {
                    event.cars = cars;
                    return event;
                });
        }).then(t.batch);
    
        return t.map('SELECT * FROM Users WHERE status = $1', ['active'], user => {
            return getEvents(user.id)
                .then(events => {
                    user.events = events;
                    return user;
                });
        }).then(t.batch);
    }
    

    这里还有一种更快的单查询方法:

    【讨论】:

      猜你喜欢
      • 2017-08-29
      • 1970-01-01
      • 2017-11-18
      • 1970-01-01
      • 2018-08-20
      • 2019-01-04
      • 2014-12-30
      • 2016-10-14
      • 1970-01-01
      相关资源
      最近更新 更多