我遇到了一些MongoDB聚合问题,我正在尝试构建。我想得到一张表,其中包含我在一周内玩一些游戏的统计数据。我需要将它放入表中,按行中的游戏和列中的星期几来排序。单元格将包含一天中每个游戏玩量的百分比(意味着100%是在具体日期中玩的所有游戏的总数)。我希望将行排序按一周内某个游戏的总次数排序(最多玩游戏的周数)。这就是我希望它看到结尾的方式:
我从dickless那里得到了一个很好的建议:如何计算百分比:MongoDB aggregation - how to get a percentage value of how many times an event occurred per day of week
我目前的聚合如下:
db.games.aggregate([
{ $project: {
"_id": 0,
"date" : { $dayOfWeek: "$date" },
"title": "$title"
} },
{ $group: {
"_id": { "title": "$title", "date": "$date" },
"total": { $sum: 1 }
} },
{ $group: {
"_id": "$_id.date",
"types": { $push: { "title": "$_id.title", total: "$total" } },
"grandTotal": { $sum: "$total" }
} },
{ $unwind: "$types"},
{ $project: {
"_id": 0,
"title": "$types.title",
"percentage": { $divide: [ "$types.total", "$grandTotal" ] },
"day": { $arrayElemAt: [ [ "0", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], "$_id" ] }
} },
{ $group: {
"_id": "$title",
"days": {$push: {"day":"$day", "percentage": "$percentage"} }
} }
])
这是我从中得到的JSON:
/* 1 */
{
"_id" : "Bomberman",
"days" : [
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Wed",
"percentage" : 0.09090909090909091
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
]
},
/* 2 */
{
"_id" : "GTA",
"days" : [
{
"day" : "Tue",
"percentage" : 0.4
},
{
"day" : "Mon",
"percentage" : 0.375
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Fri",
"percentage" : 0.3333333333333333
}
]
},
/* 3 */
{
"_id" : "Forza",
"days" : [
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Fri",
"percentage" : 0.25
}
]
},
/* 4 */
{
"_id" : "Pacman",
"days" : [
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Mon",
"percentage" : 0.125
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
]
},
/* 5 */
{
"_id" : "BattleField",
"days" : [
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Fri",
"percentage" : 0.25
}
]
}
这是我想要获得的JSON(从最常玩的游戏到最少玩的游戏):
/* 1 */
{
"_id" : "GTA",
"days" : [
{
"day" : "Mon",
"percentage" : 0.375
},
{
"day" : "Tue",
"percentage" : 0.4
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Fri",
"percentage" : 0.3333333333333333
}
]
},
/* 2 */
{
"_id" : "BattleField",
"days" : [
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Fri",
"percentage" : 0.25
}
]
}
/* 3 */
{
"_id" : "Forza",
"days" : [
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.25
}
]
},
/* 4 */
{
"_id" : "Pacman",
"days" : [
{
"day" : "Mon",
"percentage" : 0.125
},
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
]
},
/* 5 */
{
"_id" : "Bomberman",
"days" : [
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Wed",
"percentage" : 0.09090909090909091
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
]
},
数据输入到DB:
[
{"title":"GTA","date":"2017-11-13"},
{"title":"GTA","date":"2017-11-13"},
{"title":"GTA","date":"2017-11-13"},
{"title":"Pacman","date":"2017-11-13"},
{"title":"BattleField","date":"2017-11-13"},
{"title":"BattleField","date":"2017-11-13"},
{"title":"Forza","date":"2017-11-13"},
{"title":"Forza","date":"2017-11-13"},
{"title":"GTA","date":"2017-11-14"},
{"title":"GTA","date":"2017-11-14"},
{"title":"GTA","date":"2017-11-14"},
{"title":"GTA","date":"2017-11-14"},
{"title":"BattleField","date":"2017-11-14"},
{"title":"BattleField","date":"2017-11-14"},
{"title":"Forza","date":"2017-11-14"},
{"title":"Pacman","date":"2017-11-14"},
{"title":"Bomberman","date":"2017-11-14"},
{"title":"Bomberman","date":"2017-11-14"},
{"title":"GTA","date":"2017-11-15"},
{"title":"GTA","date":"2017-11-15"},
{"title":"GTA","date":"2017-11-15"},
{"title":"BattleField","date":"2017-11-15"},
{"title":"BattleField","date":"2017-11-15"},
{"title":"BattleField","date":"2017-11-15"},
{"title":"Forza","date":"2017-11-15"},
{"title":"Forza","date":"2017-11-15"},
{"title":"Pacman","date":"2017-11-15"},
{"title":"Pacman","date":"2017-11-15"},
{"title":"Bomberman","date":"2017-11-15"},
{"title":"GTA","date":"2017-11-16"},
{"title":"GTA","date":"2017-11-16"},
{"title":"BattleField","date":"2017-11-16"},
{"title":"BattleField","date":"2017-11-16"},
{"title":"Forza","date":"2017-11-16"},
{"title":"Bomberman","date":"2017-11-16"},
{"title":"Pacman","date":"2017-11-16"},
{"title":"GTA","date":"2017-11-17"},
{"title":"GTA","date":"2017-11-17"},
{"title":"GTA","date":"2017-11-17"},
{"title":"GTA","date":"2017-11-17"},
{"title":"BattleField","date":"2017-11-17"},
{"title":"BattleField","date":"2017-11-17"},
{"title":"BattleField","date":"2017-11-17"},
{"title":"Forza","date":"2017-11-17"},
{"title":"Forza","date":"2017-11-17"},
{"title":"Forza","date":"2017-11-17"},
{"title":"Bomberman","date":"2017-11-17"},
{"title":"Pacman","date":"2017-11-17"}
]
现在我的问题是如何根据每周最常玩的游戏对行进行排序?我想我需要创建一些子聚合或子管道,我将在哪里计算每个游戏的总播放次数,然后将此结果传递到我的聚合的末尾进行排序,但我找不到这样做的方法。
我真的是一个MongoDB菜鸟,所以我将不胜感激任何建议,谢谢!
答案 0 :(得分:0)
感谢Alex Blex指出我正确的方法,这是上述问题的解决方案:
db.games.aggregate([
{ $project: {
"_id": 0,
"date" : { $dayOfWeek: "$date" },
"title": "$title"
} },
{ $group: {
"_id": { "title": "$title", "date": "$date" },
"total": { $sum: 1 }
} },
{ $group: {
"_id": "$_id.date",
"types": { $push: { "title": "$_id.title", total: "$total" } },
"grandTotal": { $sum: "$total" }
} },
{ $sort: {
"_id": 1
} }, // This sorts the arrays with days from Monday to Sunday
{ $unwind: "$types"},
{ $project: {
"_id": 0,
"title": "$types.title",
"percentage": { $divide: [ "$types.total", "$grandTotal" ] },
"day": { $arrayElemAt: [ [ "0", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], "$_id" ] },
"supertotal" : "$types.total" // This exposes the total numbers of times a game was played per particular dayOfWeek
} },
{ $group: {
"_id": "$title",
"days": {$push: {"day":"$day", "percentage": "$percentage"} },
"supertotal" : {$sum: "$supertotal"} // This sums the total numbers of times a game was played in a week
} },
{ $sort: {
"supertotal": -1
} } // This sorts the documents from the most played game
])
最终JSON:
/* 1 */
{
"_id" : "GTA",
"days" : [
{
"day" : "Mon",
"percentage" : 0.375
},
{
"day" : "Tue",
"percentage" : 0.4
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Fri",
"percentage" : 0.3333333333333333
}
],
"supertotal" : 16.0
},
/* 2 */
{
"_id" : "BattleField",
"days" : [
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Wed",
"percentage" : 0.2727272727272727
},
{
"day" : "Thu",
"percentage" : 0.2857142857142857
},
{
"day" : "Fri",
"percentage" : 0.25
}
],
"supertotal" : 12.0
},
/* 3 */
{
"_id" : "Forza",
"days" : [
{
"day" : "Mon",
"percentage" : 0.25
},
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.25
}
],
"supertotal" : 9.0
},
/* 4 */
{
"_id" : "Pacman",
"days" : [
{
"day" : "Mon",
"percentage" : 0.125
},
{
"day" : "Tue",
"percentage" : 0.1
},
{
"day" : "Wed",
"percentage" : 0.18181818181818182
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
],
"supertotal" : 6.0
},
/* 5 */
{
"_id" : "Bomberman",
"days" : [
{
"day" : "Tue",
"percentage" : 0.2
},
{
"day" : "Wed",
"percentage" : 0.09090909090909091
},
{
"day" : "Thu",
"percentage" : 0.14285714285714285
},
{
"day" : "Fri",
"percentage" : 0.08333333333333333
}
],
"supertotal" : 5.0
}