集計フレームワークを使用して集計を計算することができます。これは、Map/Reduceの一般的な集約操作のためのより速い代替手段です。 MongoDBでは、パイプラインは、データレコードを処理して計算結果を返すためにコレクションに適用される一連の特殊演算子で構成されます。集計操作では、複数の文書の値をグループ化し、グループ化されたデータに対してさまざまな操作を実行して単一の結果を返すことができます。詳細は、documentationをご覧ください。
は、所望の結果を取得するために、次のパイプラインを実行して検討して上記パイプラインで
var pipeline = [
{ "$unwind": "$userPicks" },
{
"$group": {
"_id": {
"week": "$week",
"user": "$userPicks.user"
},
"weeklyScore": {
"$sum": {
"$cond": [
{ "$eq": ["$userPicks.chosenTeam", "$winner"] },
1, 0
]
}
}
}
},
{
"$group": {
"_id": "$_id.user",
"weeklyScores": {
"$push": {
"week": "$_id.week",
"score": "$weeklyScore"
}
},
"totalScores": { "$sum": "$weeklyScore" }
}
}
];
Game.aggregate(pipeline, function(err, results){
User.populate(results, { "path": "_id" }, function(err, results) {
if (err) throw err;
console.log(JSON.stringify(results, undefined, 4));
});
})
を、最初のステップは、非常に来る$unwind
オペレータ
{ "$unwind": "$userPicks" }
ありますデータが配列として格納されるときに便利です。アンワインド演算子がリストデータフィールドに適用されると、アンワインドが適用されるリストデータフィールドのすべての要素ごとに新しいレコードが生成されます。基本的にデータを平坦化します。
これは、次のパイプラインのステージのために必要な操作、$group
パイプライン演算子は、に似ている、あなたのグループフィールドweek
と"userPicks.user"
{
"$group": {
"_id": {
"week": "$week",
"user": "$userPicks.user"
},
"weeklyScore": {
"$sum": {
"$cond": [
{ "$eq": ["$userPicks.chosenTeam", "$winner"] },
1, 0
]
}
}
}
}
により平坦化文書$group
ステップですSQLのGROUP BY
節。 SQLでは、集約関数を使用しない限り、GROUP BY
は使用できません。同じように、MongoDBでも集約関数を使用する必要があります。集計関数hereの詳細を読むことができます。それは最初の引数だとして、この$group
動作で
は、(彼らは毎週正しく予測するサッカーの試合の数IE)各ユーザの毎週のスコアを計算するためのロジックは、三項演算論理条件をとる$cond
を介して行われます(if)を返し、評価が真(then)である第2引数または第3引数(false)を返します。
"$cond": [
{ "$eq": ["$userPicks.chosenTeam", "$winner"] },
1, 0
]
ので、文書内、"$userPicks.chosenTeam"
フィールドは"$winner"
フィールドと同じで処理されている場合$cond
オペレータフィード:これは、1と0に真/偽を返すが、それぞれ$sum
にフィードすることができますそれ以外の場合は値1を加算してゼロ値を加算します。
第二群のパイプライン:
{
"$group": {
"_id": "$user",
"weeklyScores": {
"$push": {
"week": "$_id.week",
"score": "$weeklyScore"
}
},
"totalScores": { "$sum": "$weeklyScore" }
}
}
は、前のパイプラインからの文書を取得し、グループにそれらをさらにuser
フィールドによって、および$sum
アキュムレータ演算子を使用して、別の集約すなわち合計スコアを算出します。同じパイプライン内で、$push
演算子を使用すると、各グループの式の値の配列を返すことで、週単位のスコアのリストを集計できます。
パイプラインを実行するときに、MongoDBは演算子をパイプでパイプすることに注意してください。ここで "Pipe"はLinuxの意味をとります。演算子の出力は、次の演算子の入力になります。各演算子の結果は、新しい文書集合です。 Mongoのは、上記のパイプラインを実行して、次のように:
collection | $unwind | $group | $group => result
を今、あなたはマングースにおけるアグリゲーションパイプラインを実行すると、結果がユーザーIDです_id
キーを持つことになりますし、あなたがこの分野、すなわち上の結果を移入する必要がありますMongooseはユーザーコレクションに対して「結合」を実行し、ユーザースキーマを持つ文書を結果に返します。パイプラインを理解することを支援するか、またはそれをデバッグする
側の注意点として
は、あなただけの最初のパイプライン演算子と集約を実行し、予期しない結果を取得する必要があります。たとえば、としてのmongoシェルで集約を実行します。
db.games.aggregate([
{ "$unwind": "$userPicks" }
])
userPicks
配列が適切に解体されたかどうかを確認するために、結果を確認してください。それが期待される結果を与える場合は、次を追加します。
db.games.aggregate([
{ "$unwind": "$userPicks" },
{
"$group": {
"_id": {
"week": "$week",
"user": "$userPicks.user"
},
"weeklyScore": {
"$sum": {
"$cond": [
{ "$eq": ["$userPicks.chosenTeam", "$winner"] },
1, 0
]
}
}
}
}
])
あなたが最後のパイプラインステップに得るまでの手順を繰り返します。
こんにちは、機械学習のこの部分ですか?どのようにホームスコアを計算したいですか?それは前の得点からの増分ですか? – vdj4y