2017-01-31 2 views
11

user,nounおよびusernoun(PHP/Eloquentではuser_noun)の3つのモデルがあります。 usernounの間に多対多の関係があります。 「ピボット」テーブルには、追加の属性scoreがあります。私は、ユーザーがユーザーの合計スコアを取得する必要があり、各名詞のスコアを合計する雄弁で、このクエリを使用することができます。ウォーターラインまたはMongoDBでの選択、グループ化、および結合方法

$users = User::leftJoin('noun_user', 'user.id', 'noun_user.user_id') 
    ->groupBy('user.id') 
    ->select('user.*', DB::raw('sum(noun_user.score) as score')) 
    ->orderBy('score', 'desc') 
    ->get(); 

しかし、私は、これはウォーターラインで動作するように取得する方法を見つけ出すことはできません。これは機能しますが、.populate('user')行のコメントを外すと表示されません。入力するにはuserが必要です。ここ

UserNoun 
    .find({}) 
    //.populate('user') 
    .groupBy('user') 
    .sum('score') 
    .sort({ score: 'desc' }) 
    .exec((err, usernouns) => { 
    return res.json(usernouns) 
}) 

作品.native()クエリです:

UserNoun.native(function(err, collection) { 
    collection.aggregate([ 
     { 
      $lookup: { 
       from: 'user', 
       localField: 'user', 
       foreignField: '_id', 
       as: 'user' 
      } 
     }, 
     { 
      $group: { _id: '$user', total: { $sum: '$score' } } 
     }, 
     { 
      $sort : { total: -1 } 
     } 
    ]).toArray(function (err, results) { 
     return res.json(results) 
    }) 
}) 

は、このネイティブクエリがgroupBypopulatesumとウォーターラインに書き換えることができますか?

答えて

0

今のように水線で結合することはできません。そのために生のクエリを使用する必要があります。 populateは関連するフィールドに値を設定しますが、結果が返されません。合計のみ()と組み合わせ にGROUPBYの使用をサポートし、この時点で

ウォーターラインは、GROUPBYについては

など)(カウントおよびソート次使用することができます。

Model.find() 
.groupBy('term') 
.sum('count') 
.limit(20) 
.sort({count: 'desc'}) 
.exec(function (err, data){ 
//Your code here.. 
}); 
+0

groupBy'と 'sum'メソッドはありますか? – Sangharsh

+0

正確な文書を見つけることができませんでしたが、私はクエリを試しました。sailsのgroupbyは、計算機能で動作します。 1つのリンクが見つかりました - http://stackoverflow.com/questions/20254910/how-do-i-perform-this-query-using-sailsjs-orm-waterline –

5

として、 [email protected]の場合、これを行う唯一の方法はネイティブクエリを使用することです。ところで

、あなたはUserモデルの内側にあなたの方法をエクスポートすることができます。

// User.js 
module.exports = { 

    // ... 

    findTotalScores: function (callback) { 
     UserNoun.native(function(err, collection) { 
      if (err) { 
       return callback(err); 
      } 

      collection.aggregate([ 
       { 
        $lookup: { 
         from: 'user', 
         localField: 'user', 
         foreignField: '_id', 
         as: 'user' 
        } 
       }, 
       { 
        $group: { _id: '$user', total: { $sum: '$score' } } 
       }, 
       { 
        $sort : { total: -1 } 
       } 
      ]).toArray(callback); 
     }); 
    } 

}; 

そして、あなたが呼び出すことによって、あなたのコントローラで使用することができます:あなたは `のための参照リンクを共有してくださいすることができ

User.findTotalScores(function (err, results) { 
    return res.json(results); 
}); 
関連する問題