使用 pg-promise 的嵌套查询对象映射
Nested query object mapping with pg-promise
我正在看一个来自 pg-promise for method 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 = ', ['active'], user => {
return t.any('SELECT * FROM Events WHERE userId = ', user.id)
.then(events=> {
user.events = events;
return user;
});
}).then(t.batch);
})
.then(data => {
// success
})
.catch(error => {
// error
});
假设 Event
实体与例如Cars
,我想列出每个event
连接的所有cars
,当我想要的对象超过一层深度时,如何使用map函数?
我想要的结果可能是这样的:
[{
//This is a user
id: 2,
first_name: "John",
last_name: "Doe",
events: [{
id: 4,
type: 'type',
cars: [{
id: 4,
brand: 'bmw'
}]
}]
}]
我是 pg-promise 的作者。
function getUsers(t) {
return t.map('SELECT * FROM Users WHERE status = ', ['active'], user => {
return t.map('SELECT * FROM Events WHERE userId = ', user.id, event => {
return t.any('SELECT * FROM Cars WHERE eventId = ', 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 simplifies mapping retrieved rows into something else, and since we map them into promises, those need to be settled, for which we use method batch。我们为 cars
的每个内部请求数组执行此操作,然后在顶层 - 解决 events
.
的请求数组
更新
如果将树逻辑颠倒过来,可能更容易阅读和维护:
function getUsers(t) {
const getCars = eventId => t.any('SELECT * FROM Cars WHERE eventId = ', eventId);
const getEvents = userId => t.map('SELECT * FROM Events WHERE userId = ', userId, event => {
return getCars(event.id)
.then(cars => {
event.cars = cars;
return event;
});
}).then(t.batch);
return t.map('SELECT * FROM Users WHERE status = ', ['active'], user => {
return getEvents(user.id)
.then(events => {
user.events = events;
return user;
});
}).then(t.batch);
}
这里还有一种更快的单一查询方法:
我正在看一个来自 pg-promise for method 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 = ', ['active'], user => {
return t.any('SELECT * FROM Events WHERE userId = ', user.id)
.then(events=> {
user.events = events;
return user;
});
}).then(t.batch);
})
.then(data => {
// success
})
.catch(error => {
// error
});
假设 Event
实体与例如Cars
,我想列出每个event
连接的所有cars
,当我想要的对象超过一层深度时,如何使用map函数?
我想要的结果可能是这样的:
[{
//This is a user
id: 2,
first_name: "John",
last_name: "Doe",
events: [{
id: 4,
type: 'type',
cars: [{
id: 4,
brand: 'bmw'
}]
}]
}]
我是 pg-promise 的作者。
function getUsers(t) {
return t.map('SELECT * FROM Users WHERE status = ', ['active'], user => {
return t.map('SELECT * FROM Events WHERE userId = ', user.id, event => {
return t.any('SELECT * FROM Cars WHERE eventId = ', 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 simplifies mapping retrieved rows into something else, and since we map them into promises, those need to be settled, for which we use method batch。我们为 cars
的每个内部请求数组执行此操作,然后在顶层 - 解决 events
.
更新
如果将树逻辑颠倒过来,可能更容易阅读和维护:
function getUsers(t) {
const getCars = eventId => t.any('SELECT * FROM Cars WHERE eventId = ', eventId);
const getEvents = userId => t.map('SELECT * FROM Events WHERE userId = ', userId, event => {
return getCars(event.id)
.then(cars => {
event.cars = cars;
return event;
});
}).then(t.batch);
return t.map('SELECT * FROM Users WHERE status = ', ['active'], user => {
return getEvents(user.id)
.then(events => {
user.events = events;
return user;
});
}).then(t.batch);
}
这里还有一种更快的单一查询方法: