1

メソッドmapの pg-promiseの例を見ていきます。

// 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エンティティが eg と 1 対多の関係にあり、それぞれに接続されているCarsすべてを一覧表示したいとします。必要なオブジェクトが 1 レベル以上の深さである場合、どのようにmap関数を使用できますか?carsevent

私が望む結果は次のようになります。

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

1 に答える 1

5

私は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);
}

ここで見つけることができる、より高速な単一クエリのアプローチもあります。

于 2016-10-27T00:45:21.803 に答える