2016-10-26 283 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的請求數組。


還有,可以在這裏找到一個更快,單查詢方法: