【问题标题】:Passing a value from one part of the MongoDB aggregation to another to sort the results将值从 MongoDB 聚合的一部分传递到另一部分以对结果进行排序
【发布时间】:2018-05-06 03:12:24
【问题描述】:

我在尝试构建 MongoDB 聚合时遇到了一些问题。我想获得一张表格,其中包含我在一周内玩了多少游戏的统计数据。我需要将它放入按游戏按行排序的表格中,并按列按一周中的天数排序。单元格将包含一天中每场比赛的百分比(意味着 100% 是具体一天中所有比赛的总数)。我希望按一周内玩某个游戏的总次数对行进行排序(最常玩游戏的周数排在最前面)。这就是我希望它最后的样子:

final table

我从 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
        }
    ]
},

输入数据库的数据:

[
{"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 菜鸟,所以我会很感激任何关于这方面的建议,谢谢!

【问题讨论】:

  • 你期望的结果是什么?将它的json添加到问题中
  • 感谢您的建议,我在当前获取的 JSON 下添加了预期的 JSON
  • 在最后一个投影中暴露"$types.total",在下面的组中求和,之后添加一个排序阶段。
  • 太好了,它有效!非常感谢:)

标签: mongodb sorting aggregation


【解决方案1】:

感谢 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
}

【讨论】:

    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 2017-07-26
    • 2011-07-07
    • 1970-01-01
    相关资源
    最近更新 更多