pg-promise任务并映射多个相同级别的嵌套查询

我使用node和pg-promise来创build一个基本的rest API,并且在查询特定用户的所有数据时遇到了一些问题。 以下是返回的数据应该是什么样的。 地址,电话号码和技能都住在不同的表格中。 我没有问题检索地址或电话号码,只是我似乎无法得到的技能。 不太确定如何在主查询后获得多个查询,以获取所有这些其他字段,请参阅附加的代码以供参考,我将很乐意回答任何问题。


{ "user_id": 1, "first_name": "Eugene", "last_name": "Hanson", "display_name": "Eugene Hanson", "email": "ehanson0@typepad.com", "hash": "88a6aa27235d2e39dd9cb854cc246487147050f265578a3e1aee35be5db218ef", "privilege_id": 14, "seniority": 1, "birthday": "19-11-1940 00:00:00.0", "shift_count_total": 587, "shift_count_year": 62, "address_id": 1, "street": "92 Schmedeman Lane", "city": "Fort Smith", "state": "AR", "zip": 72905, "phone_numbers": [ { "phone_number": "62-(705)636-2916", "name": "PRIMARY" } ], "skills": [ "Head Audio", "Head Video", "Head Electrician", "Carpenter", "rigger" ] } 

  function getAllUsers() { // console.time("answer time") var deferred = Q.defer(); db.task(t => { return t.map('SELECT * \ FROM users \ JOIN addresses \ ON users.address_id = addresses.address_id',[], user => { var user_id = user.user_id; // console.log(user_id) console.time("answer time") return t.manyOrNone('SELECT phone_numbers.phone_number, phone_types.name \ FROM users \ JOIN users_phone_numbers \ ON users.user_id = users_phone_numbers.user_id \ JOIN phone_numbers \ ON users_phone_numbers.phone_id = phone_numbers.phone_id \ JOIN phone_types \ ON phone_numbers.phone_type_id = phone_types.phone_type_id \ WHERE users.user_id = $1', user.user_id) .then(phone_numbers=> { // logger.log('info', phone_numbers) user.phone_numbers = phone_numbers; return user; }) }).then(t.batch); }) .then(data => { // console.log(data) console.timeEnd("answer time"); var response = {code: "200", message: "", payload: data}; deferred.resolve(response); }) .catch(error => { var response = {code: error.code, message: error.message, payload: ""}; logger.log('error', error) deferred.reject(response) }); 

我是pg-promise的作者。


你的function的简化版本将是:

 function getAllUsers() { return db.task(t => { return t.map('SELECT * FROM users', [], user => { return t.batch([ t.any('SELECT * FROM phones'), // plus formatting params t.any('SELECT * FROM skills'), // plus formatting params ]) .then(data => { user.phones = data[0]; user.skills = data[1]; return user; }); }).then(t.batch); }); } getAllUsers() .then(data => { // data tree }) .catch(error => { // error }); 

如果您使用蓝鸟作为承诺库,那么您可以replace此代码:

 .then(data => { user.phones = data[0]; user.skills = data[1]; return user; }); 

与这一个:

 .spread((phones, skills) => { user.phones = phones; user.skills = skills; return user; }); 

而不要使用像var deferred = Q.defer(); ,那里不需要。 图书馆已经基于承诺。

要获得高性能替代,请参阅: 使用PostgreSQL / NodeJS将JOIN表作为结果数组 。