2017-04-04 19 views
2

私はnodeとpg-promiseを使って基本的な残りのAPIを作成していますが、特定のユーザのすべてのデータをクエリする際に問題があります。以下は、返されるデータの外観です。住所、電話番号、およびスキルはすべて別々のテーブルに保存されています。私はアドレスや電話番号を取得することに問題はなく、私は得ることができないそのスキルを持っています。これらの他のフィールドをすべて取得するためのメインクエリの後に複数のクエリを設定する方法が不明な場合は、添付のコードを参考にしてください。質問にお答えします。複数の同じレベルのネストされたクエリを持つpg-promiseタスクとマップ


{ 
"user_id": 1, 
"first_name": "Eugene", 
"last_name": "Hanson", 
"display_name": "Eugene Hanson", 
"email": "[email protected]", 
"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) 
 
});

+0

問題は何ですか?代わりに何を得ていますか?あなたの '.catch'ハンドラはどこですか? )答えが出る前に質問を正しく終わらせる必要があります; –

+0

オリジナルの投稿を編集して、誤ってコピーして貼り付けていた「.catch」を追加しました。申し訳ありませんが、私の質問は明確ではない、私は何をしようとしているすべてのユーザーを通過し、その後、さまざまな他のテーブルから関連付けられたデータをすべて取得し、ユーザーレコードに戻してクライアントに戻します。私は現在、電話番号のためにのみこれを行うことができます。マップを使ってスキルを得るために、別のクエリをどのように追加するかわかりません。どんなアドバイスも歓迎され、私がもっと明確にする必要があるかどうか私に知らせてください。 – seanpdiaz

答えて

1

私はpg-promiseの著者です。


あなたの関数の

簡易版は、次のようになります

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

そして、あなたが約束ライブラリとしてbluebirdを使用している場合、あなたはこのコードを置き換えることができます。この1と

.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();のようなものは使用しないでください。必要ありません。図書館はすでに約束しています。

高性能の代替品については、get JOIN table as array of results with PostgreSQL/NodeJSを参照してください。

+0

**ありがとうございました**これは私が必要としていたものです。私はこれらの作品を一緒に置く方法についてインターネット上で狩りをしていましたが、明確なアイデアを見つけることができず、あなたはそれに光を当てることができました。 – seanpdiaz

+0

@seanpdiazようこそ。私は答えを更新しました;) –

+0

私の電話をもっと魅力的なものにする方法を正しい方向に指してくれてありがとう、私はあなたが提供したリンクを使用して、12,000ミリ秒から500ミリ秒までダウンしました。 **ありがとうございました。 – seanpdiaz

関連する問題