您可以使用聚合框架來計算聚合。這是用於常見聚合操作的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
操作,計算每個用戶每週分數(即它們每星期正確預測足球比賽的數量)的邏輯通過三元運算符$cond
,需要一個邏輯條件進行,因爲它是第一個參數(if),然後返回評估爲true的第二個參數(then)或第三個參數爲false(else)。這使得真/假返回到1和0至饋送到$sum
分別爲:
"$cond": [
{ "$eq": ["$userPicks.chosenTeam", "$winner"] },
1, 0
]
所以,如果在文檔中被處理的"$userPicks.chosenTeam"
場是一樣的"$winner"
領域,$cond
操作者進料總和值1總計爲零值。
第二組管道:
{
"$group": {
"_id": "$user",
"weeklyScores": {
"$push": {
"week": "$_id.week",
"score": "$weeklyScore"
}
},
"totalScores": { "$sum": "$weeklyScore" }
}
}
從以前的管道,並將它們進一步組由user
字段取的文件,並計算另一骨料即總分,使用$sum
累加器運算符。在同一管道中,您可以使用運算符將每週得分列表聚合,該運算符將爲每個組返回一組表達式值數組。
在這裏需要注意的一件事是執行一個管道時,MongoDB將管道操作符互相管道。這裏的「管道」採用Linux的含義:操作員的輸出成爲後面的操作員的輸入。每個操作員的結果都是一個新的文檔集合。所以蒙戈執行上述的管道如下:
collection | $unwind | $group | $group => result
現在,當您運行貓鼬聚合管道,其結果將有_id
關鍵是用戶ID,您需要填寫此字段即結果Mongoose將對用戶集合執行「加入」,並返回結果中包含用戶模式的文檔。爲了幫助理解流水線或調試它,如果您得到意想不到的結果,請使用第一個流水線運算符運行聚合。例如,在運行蒙戈聚集殼牌:
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