2016-10-26 276 views
1

我会通过一个实例从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,我想列出连接到每个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' 
     }] 
    }] 
}] 

回答

3

我的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简化了映射检索到的行成别的东西,因为我们把它们映射到的承诺,那些需要解决,为此,我们使用方法batch。我们针对cars的每个内部请求数组执行此操作,然后在顶层 - 请求events的请求数组。


还有,可以在这里找到一个更快,单查询方法: